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 */
62 /* U/V black value for 8-bit colour */
63 static uint8_t const eight_bit_uv = (1 << 7) - 1;
64 /* U/V black value for 9-bit colour */
65 static uint16_t const nine_bit_uv = (1 << 8) - 1;
66 /* U/V black value for 10-bit colour */
67 static uint16_t const ten_bit_uv = (1 << 9) - 1;
68 /* U/V black value for 16-bit colour */
69 static uint16_t const sixteen_bit_uv = (1 << 15) - 1;
73 Image::vertical_factor (int n) const
79 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
81 throw PixelFormatError ("line_factor()", _pixel_format);
84 return lrintf(powf(2.0f, d->log2_chroma_h));
88 Image::horizontal_factor (int n) const
94 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
96 throw PixelFormatError ("sample_size()", _pixel_format);
99 return lrintf(powf(2.0f, d->log2_chroma_w));
102 /** @param n Component index.
103 * @return Number of samples (i.e. pixels, unless sub-sampled) in each direction for this component.
106 Image::sample_size (int n) const
109 lrint (ceil (static_cast<double>(size().width) / horizontal_factor (n))),
110 lrint (ceil (static_cast<double>(size().height) / vertical_factor (n)))
114 /** @return Number of planes */
116 Image::planes () const
118 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
120 throw PixelFormatError ("planes()", _pixel_format);
123 if (_pixel_format == AV_PIX_FMT_PAL8) {
127 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
131 return d->nb_components;
137 round_width_for_subsampling (int p, AVPixFmtDescriptor const * desc)
139 return p & ~ ((1 << desc->log2_chroma_w) - 1);
145 round_height_for_subsampling (int p, AVPixFmtDescriptor const * desc)
147 return p & ~ ((1 << desc->log2_chroma_h) - 1);
151 /** Crop this image, scale it to `inter_size' and then place it in a black frame of `out_size'.
152 * @param crop Amount to crop by.
153 * @param inter_size Size to scale the cropped image to.
154 * @param out_size Size of output frame; if this is larger than inter_size there will be black padding.
155 * @param yuv_to_rgb YUV to RGB transformation to use, if required.
156 * @param out_format Output pixel format.
157 * @param out_aligned true to make the output image aligned.
158 * @param fast Try to be fast at the possible expense of quality; at present this means using
159 * fast bilinear rather than bicubic scaling.
162 Image::crop_scale_window (
163 Crop crop, dcp::Size inter_size, dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast
166 /* Empirical testing suggests that sws_scale() will crash if
167 the input image is not aligned.
169 DCPOMATIC_ASSERT (aligned ());
171 DCPOMATIC_ASSERT (out_size.width >= inter_size.width);
172 DCPOMATIC_ASSERT (out_size.height >= inter_size.height);
174 shared_ptr<Image> out (new Image(out_format, out_size, out_aligned));
177 AVPixFmtDescriptor const * in_desc = av_pix_fmt_desc_get (_pixel_format);
179 throw PixelFormatError ("crop_scale_window()", _pixel_format);
182 /* Round down so that we crop only the number of pixels that is straightforward
183 * considering any subsampling.
186 round_width_for_subsampling(crop.left, in_desc),
187 round_width_for_subsampling(crop.right, in_desc),
188 round_height_for_subsampling(crop.top, in_desc),
189 round_height_for_subsampling(crop.bottom, in_desc)
192 /* Also check that we aren't cropping more image than there actually is */
193 if ((corrected_crop.left + corrected_crop.right) >= (size().width - 4)) {
194 corrected_crop.left = 0;
195 corrected_crop.right = size().width - 4;
198 if ((corrected_crop.top + corrected_crop.bottom) >= (size().height - 4)) {
199 corrected_crop.top = 0;
200 corrected_crop.bottom = size().height - 4;
203 /* Size of the image after any crop */
204 dcp::Size const cropped_size = corrected_crop.apply (size());
206 /* Hack: if we're not doing quite the crop that we were asked for, and we carry on scaling
207 * to the inter_size we were asked for, there is a small but noticeable wobble in the image
208 * luminance (#1872). This hack means we will jump in steps of the subsampling distance
209 * in both crop and scale.
211 inter_size.width = round_width_for_subsampling(inter_size.width, in_desc);
212 inter_size.height = round_width_for_subsampling(inter_size.height, in_desc);
214 /* Scale context for a scale from cropped_size to inter_size */
215 struct SwsContext* scale_context = sws_getContext (
216 cropped_size.width, cropped_size.height, pixel_format(),
217 inter_size.width, inter_size.height, out_format,
218 fast ? SWS_FAST_BILINEAR : SWS_BICUBIC, 0, 0, 0
221 if (!scale_context) {
222 throw runtime_error (N_("Could not allocate SwsContext"));
225 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
226 int const lut[dcp::YUV_TO_RGB_COUNT] = {
231 /* The 3rd parameter here is:
232 0 -> source range MPEG (i.e. "video", 16-235)
233 1 -> source range JPEG (i.e. "full", 0-255)
235 0 -> destination range MPEG (i.e. "video", 16-235)
236 1 -> destination range JPEG (i.e. "full", 0-255)
238 But remember: sws_setColorspaceDetails ignores
239 these parameters unless the image isYUV or isGray
240 (if it's neither, it uses video range for source
243 sws_setColorspaceDetails (
245 sws_getCoefficients (lut[yuv_to_rgb]), 0,
246 sws_getCoefficients (lut[yuv_to_rgb]), 0,
250 /* Prepare input data pointers with crop */
251 uint8_t* scale_in_data[planes()];
252 for (int c = 0; c < planes(); ++c) {
253 int const x = lrintf(bytes_per_pixel(c) * corrected_crop.left);
254 scale_in_data[c] = data()[c] + x + stride()[c] * (corrected_crop.top / vertical_factor(c));
257 AVPixFmtDescriptor const * out_desc = av_pix_fmt_desc_get (out_format);
259 throw PixelFormatError ("crop_scale_window()", out_format);
262 /* Corner of the image within out_size */
263 Position<int> const corner (
264 round_width_for_subsampling((out_size.width - inter_size.width) / 2, out_desc),
265 round_height_for_subsampling((out_size.height - inter_size.height) / 2, out_desc)
268 uint8_t* scale_out_data[out->planes()];
269 for (int c = 0; c < out->planes(); ++c) {
270 int const x = lrintf(out->bytes_per_pixel(c) * corner.x);
271 scale_out_data[c] = out->data()[c] + x + out->stride()[c] * (corner.y / out->vertical_factor(c));
276 scale_in_data, stride(),
277 0, cropped_size.height,
278 scale_out_data, out->stride()
281 sws_freeContext (scale_context);
283 if (corrected_crop != Crop() && cropped_size == inter_size) {
284 /* We are cropping without any scaling or pixel format conversion, so FFmpeg may have left some
285 data behind in our image. Clear it out. It may get to the point where we should just stop
286 trying to be clever with cropping.
288 out->make_part_black (corner.x + cropped_size.width, out_size.width - cropped_size.width);
295 Image::convert_pixel_format (dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
297 return scale(size(), yuv_to_rgb, out_format, out_aligned, fast);
300 /** @param out_size Size to scale to.
301 * @param yuv_to_rgb YUVToRGB transform transform to use, if required.
302 * @param out_format Output pixel format.
303 * @param out_aligned true to make an aligned output image.
304 * @param fast Try to be fast at the possible expense of quality; at present this means using
305 * fast bilinear rather than bicubic scaling.
308 Image::scale (dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
310 /* Empirical testing suggests that sws_scale() will crash if
311 the input image is not aligned.
313 DCPOMATIC_ASSERT (aligned ());
315 shared_ptr<Image> scaled (new Image (out_format, out_size, out_aligned));
317 struct SwsContext* scale_context = sws_getContext (
318 size().width, size().height, pixel_format(),
319 out_size.width, out_size.height, out_format,
320 (fast ? SWS_FAST_BILINEAR : SWS_BICUBIC) | SWS_ACCURATE_RND, 0, 0, 0
323 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
324 int const lut[dcp::YUV_TO_RGB_COUNT] = {
329 /* The 3rd parameter here is:
330 0 -> source range MPEG (i.e. "video", 16-235)
331 1 -> source range JPEG (i.e. "full", 0-255)
333 0 -> destination range MPEG (i.e. "video", 16-235)
334 1 -> destination range JPEG (i.e. "full", 0-255)
336 But remember: sws_setColorspaceDetails ignores
337 these parameters unless the image isYUV or isGray
338 (if it's neither, it uses video range for source
341 sws_setColorspaceDetails (
343 sws_getCoefficients (lut[yuv_to_rgb]), 0,
344 sws_getCoefficients (lut[yuv_to_rgb]), 0,
352 scaled->data(), scaled->stride()
355 sws_freeContext (scale_context);
360 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
362 Image::yuv_16_black (uint16_t v, bool alpha)
364 memset (data()[0], 0, sample_size(0).height * stride()[0]);
365 for (int i = 1; i < 3; ++i) {
366 int16_t* p = reinterpret_cast<int16_t*> (data()[i]);
367 int const lines = sample_size(i).height;
368 for (int y = 0; y < lines; ++y) {
369 /* We divide by 2 here because we are writing 2 bytes at a time */
370 for (int x = 0; x < line_size()[i] / 2; ++x) {
373 p += stride()[i] / 2;
378 memset (data()[3], 0, sample_size(3).height * stride()[3]);
383 Image::swap_16 (uint16_t v)
385 return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
389 /* This was a lambda in the original code */
392 y_part (Image* image, int start, int width)
394 int const bpp = image->bytes_per_pixel(0);
395 int const h = image->sample_size(0).height;
396 int const s = image->stride()[0];
397 uint8_t* p = image->data()[0];
398 for (int y = 0; y < h; ++y) {
399 memset (p + start * bpp, 0, width * bpp);
406 Image::make_part_black (int const start, int const width)
408 switch (_pixel_format) {
409 case AV_PIX_FMT_RGB24:
410 case AV_PIX_FMT_ARGB:
411 case AV_PIX_FMT_RGBA:
412 case AV_PIX_FMT_ABGR:
413 case AV_PIX_FMT_BGRA:
414 case AV_PIX_FMT_RGB555LE:
415 case AV_PIX_FMT_RGB48LE:
416 case AV_PIX_FMT_RGB48BE:
417 case AV_PIX_FMT_XYZ12LE:
419 int const h = sample_size(0).height;
420 int const bpp = bytes_per_pixel(0);
421 int const s = stride()[0];
422 uint8_t* p = data()[0];
423 for (int y = 0; y < h; y++) {
424 memset (p + start * bpp, 0, width * bpp);
429 case AV_PIX_FMT_YUV420P:
431 y_part (this, start, width);
432 for (int i = 1; i < 3; ++i) {
433 uint8_t* p = data()[i];
434 int const h = sample_size(i).height;
435 for (int y = 0; y < h; ++y) {
436 for (int x = start / 2; x < (start + width) / 2; ++x) {
444 case AV_PIX_FMT_YUV422P10LE:
446 y_part (this, start, width);
447 for (int i = 1; i < 3; ++i) {
448 int16_t* p = reinterpret_cast<int16_t*>(data()[i]);
449 int const h = sample_size(i).height;
450 for (int y = 0; y < h; ++y) {
451 for (int x = start / 2; x < (start + width) / 2; ++x) {
454 p += stride()[i] / 2;
460 throw PixelFormatError ("make_part_black()", _pixel_format);
467 switch (_pixel_format) {
468 case AV_PIX_FMT_YUV420P:
469 case AV_PIX_FMT_YUV422P:
470 case AV_PIX_FMT_YUV444P:
471 case AV_PIX_FMT_YUV411P:
472 memset (data()[0], 0, sample_size(0).height * stride()[0]);
473 memset (data()[1], eight_bit_uv, sample_size(1).height * stride()[1]);
474 memset (data()[2], eight_bit_uv, sample_size(2).height * stride()[2]);
477 case AV_PIX_FMT_YUVJ420P:
478 case AV_PIX_FMT_YUVJ422P:
479 case AV_PIX_FMT_YUVJ444P:
480 memset (data()[0], 0, sample_size(0).height * stride()[0]);
481 memset (data()[1], eight_bit_uv + 1, sample_size(1).height * stride()[1]);
482 memset (data()[2], eight_bit_uv + 1, sample_size(2).height * stride()[2]);
485 case AV_PIX_FMT_YUV422P9LE:
486 case AV_PIX_FMT_YUV444P9LE:
487 yuv_16_black (nine_bit_uv, false);
490 case AV_PIX_FMT_YUV422P9BE:
491 case AV_PIX_FMT_YUV444P9BE:
492 yuv_16_black (swap_16 (nine_bit_uv), false);
495 case AV_PIX_FMT_YUV422P10LE:
496 case AV_PIX_FMT_YUV444P10LE:
497 yuv_16_black (ten_bit_uv, false);
500 case AV_PIX_FMT_YUV422P16LE:
501 case AV_PIX_FMT_YUV444P16LE:
502 yuv_16_black (sixteen_bit_uv, false);
505 case AV_PIX_FMT_YUV444P10BE:
506 case AV_PIX_FMT_YUV422P10BE:
507 yuv_16_black (swap_16 (ten_bit_uv), false);
510 case AV_PIX_FMT_YUVA420P9BE:
511 case AV_PIX_FMT_YUVA422P9BE:
512 case AV_PIX_FMT_YUVA444P9BE:
513 yuv_16_black (swap_16 (nine_bit_uv), true);
516 case AV_PIX_FMT_YUVA420P9LE:
517 case AV_PIX_FMT_YUVA422P9LE:
518 case AV_PIX_FMT_YUVA444P9LE:
519 yuv_16_black (nine_bit_uv, true);
522 case AV_PIX_FMT_YUVA420P10BE:
523 case AV_PIX_FMT_YUVA422P10BE:
524 case AV_PIX_FMT_YUVA444P10BE:
525 yuv_16_black (swap_16 (ten_bit_uv), true);
528 case AV_PIX_FMT_YUVA420P10LE:
529 case AV_PIX_FMT_YUVA422P10LE:
530 case AV_PIX_FMT_YUVA444P10LE:
531 yuv_16_black (ten_bit_uv, true);
534 case AV_PIX_FMT_YUVA420P16BE:
535 case AV_PIX_FMT_YUVA422P16BE:
536 case AV_PIX_FMT_YUVA444P16BE:
537 yuv_16_black (swap_16 (sixteen_bit_uv), true);
540 case AV_PIX_FMT_YUVA420P16LE:
541 case AV_PIX_FMT_YUVA422P16LE:
542 case AV_PIX_FMT_YUVA444P16LE:
543 yuv_16_black (sixteen_bit_uv, true);
546 case AV_PIX_FMT_RGB24:
547 case AV_PIX_FMT_ARGB:
548 case AV_PIX_FMT_RGBA:
549 case AV_PIX_FMT_ABGR:
550 case AV_PIX_FMT_BGRA:
551 case AV_PIX_FMT_RGB555LE:
552 case AV_PIX_FMT_RGB48LE:
553 case AV_PIX_FMT_RGB48BE:
554 case AV_PIX_FMT_XYZ12LE:
555 memset (data()[0], 0, sample_size(0).height * stride()[0]);
558 case AV_PIX_FMT_UYVY422:
560 int const Y = sample_size(0).height;
561 int const X = line_size()[0];
562 uint8_t* p = data()[0];
563 for (int y = 0; y < Y; ++y) {
564 for (int x = 0; x < X / 4; ++x) {
565 *p++ = eight_bit_uv; // Cb
567 *p++ = eight_bit_uv; // Cr
575 throw PixelFormatError ("make_black()", _pixel_format);
580 Image::make_transparent ()
582 if (_pixel_format != AV_PIX_FMT_BGRA && _pixel_format != AV_PIX_FMT_RGBA) {
583 throw PixelFormatError ("make_transparent()", _pixel_format);
586 memset (data()[0], 0, sample_size(0).height * stride()[0]);
590 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
592 /* We're blending RGBA or BGRA images */
593 DCPOMATIC_ASSERT (other->pixel_format() == AV_PIX_FMT_BGRA || other->pixel_format() == AV_PIX_FMT_RGBA);
594 int const blue = other->pixel_format() == AV_PIX_FMT_BGRA ? 0 : 2;
595 int const red = other->pixel_format() == AV_PIX_FMT_BGRA ? 2 : 0;
597 int const other_bpp = 4;
599 int start_tx = position.x;
603 start_ox = -start_tx;
607 int start_ty = position.y;
611 start_oy = -start_ty;
615 switch (_pixel_format) {
616 case AV_PIX_FMT_RGB24:
618 /* Going onto RGB24. First byte is red, second green, third blue */
619 int const this_bpp = 3;
620 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
621 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
622 uint8_t* op = other->data()[0] + oy * other->stride()[0];
623 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
624 float const alpha = float (op[3]) / 255;
625 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
626 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
627 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
635 case AV_PIX_FMT_BGRA:
637 int const this_bpp = 4;
638 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
639 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
640 uint8_t* op = other->data()[0] + oy * other->stride()[0];
641 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
642 float const alpha = float (op[3]) / 255;
643 tp[0] = op[blue] * alpha + tp[0] * (1 - alpha);
644 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
645 tp[2] = op[red] * alpha + tp[2] * (1 - alpha);
646 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
654 case AV_PIX_FMT_RGBA:
656 int const this_bpp = 4;
657 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
658 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
659 uint8_t* op = other->data()[0] + oy * other->stride()[0];
660 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
661 float const alpha = float (op[3]) / 255;
662 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
663 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
664 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
665 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
673 case AV_PIX_FMT_RGB48LE:
675 int const this_bpp = 6;
676 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
677 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
678 uint8_t* op = other->data()[0] + oy * other->stride()[0];
679 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
680 float const alpha = float (op[3]) / 255;
681 /* Blend high bytes */
682 tp[1] = op[red] * alpha + tp[1] * (1 - alpha);
683 tp[3] = op[1] * alpha + tp[3] * (1 - alpha);
684 tp[5] = op[blue] * alpha + tp[5] * (1 - alpha);
692 case AV_PIX_FMT_XYZ12LE:
694 dcp::ColourConversion conv = dcp::ColourConversion::srgb_to_xyz();
695 double fast_matrix[9];
696 dcp::combined_rgb_to_xyz (conv, fast_matrix);
697 double const * lut_in = conv.in()->lut (8, false);
698 double const * lut_out = conv.out()->lut (16, true);
699 int const this_bpp = 6;
700 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
701 uint16_t* tp = reinterpret_cast<uint16_t*> (data()[0] + ty * stride()[0] + start_tx * this_bpp);
702 uint8_t* op = other->data()[0] + oy * other->stride()[0];
703 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
704 float const alpha = float (op[3]) / 255;
706 /* Convert sRGB to XYZ; op is BGRA. First, input gamma LUT */
707 double const r = lut_in[op[red]];
708 double const g = lut_in[op[1]];
709 double const b = lut_in[op[blue]];
711 /* RGB to XYZ, including Bradford transform and DCI companding */
712 double const x = max (0.0, min (65535.0, r * fast_matrix[0] + g * fast_matrix[1] + b * fast_matrix[2]));
713 double const y = max (0.0, min (65535.0, r * fast_matrix[3] + g * fast_matrix[4] + b * fast_matrix[5]));
714 double const z = max (0.0, min (65535.0, r * fast_matrix[6] + g * fast_matrix[7] + b * fast_matrix[8]));
716 /* Out gamma LUT and blend */
717 tp[0] = lrint(lut_out[lrint(x)] * 65535) * alpha + tp[0] * (1 - alpha);
718 tp[1] = lrint(lut_out[lrint(y)] * 65535) * alpha + tp[1] * (1 - alpha);
719 tp[2] = lrint(lut_out[lrint(z)] * 65535) * alpha + tp[2] * (1 - alpha);
727 case AV_PIX_FMT_YUV420P:
729 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
730 dcp::Size const ts = size();
731 dcp::Size const os = yuv->size();
732 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
733 int const hty = ty / 2;
734 int const hoy = oy / 2;
735 uint8_t* tY = data()[0] + (ty * stride()[0]) + start_tx;
736 uint8_t* tU = data()[1] + (hty * stride()[1]) + start_tx / 2;
737 uint8_t* tV = data()[2] + (hty * stride()[2]) + start_tx / 2;
738 uint8_t* oY = yuv->data()[0] + (oy * yuv->stride()[0]) + start_ox;
739 uint8_t* oU = yuv->data()[1] + (hoy * yuv->stride()[1]) + start_ox / 2;
740 uint8_t* oV = yuv->data()[2] + (hoy * yuv->stride()[2]) + start_ox / 2;
741 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
742 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
743 float const a = float(alpha[3]) / 255;
744 *tY = *oY * a + *tY * (1 - a);
745 *tU = *oU * a + *tU * (1 - a);
746 *tV = *oV * a + *tV * (1 - a);
762 case AV_PIX_FMT_YUV420P10:
764 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
765 dcp::Size const ts = size();
766 dcp::Size const os = yuv->size();
767 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
768 int const hty = ty / 2;
769 int const hoy = oy / 2;
770 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
771 uint16_t* tU = ((uint16_t *) (data()[1] + (hty * stride()[1]))) + start_tx / 2;
772 uint16_t* tV = ((uint16_t *) (data()[2] + (hty * stride()[2]))) + start_tx / 2;
773 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
774 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (hoy * yuv->stride()[1]))) + start_ox / 2;
775 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (hoy * yuv->stride()[2]))) + start_ox / 2;
776 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
777 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
778 float const a = float(alpha[3]) / 255;
779 *tY = *oY * a + *tY * (1 - a);
780 *tU = *oU * a + *tU * (1 - a);
781 *tV = *oV * a + *tV * (1 - a);
797 case AV_PIX_FMT_YUV422P10LE:
799 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
800 dcp::Size const ts = size();
801 dcp::Size const os = yuv->size();
802 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
803 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
804 uint16_t* tU = ((uint16_t *) (data()[1] + (ty * stride()[1]))) + start_tx / 2;
805 uint16_t* tV = ((uint16_t *) (data()[2] + (ty * stride()[2]))) + start_tx / 2;
806 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
807 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (oy * yuv->stride()[1]))) + start_ox / 2;
808 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (oy * yuv->stride()[2]))) + start_ox / 2;
809 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
810 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
811 float const a = float(alpha[3]) / 255;
812 *tY = *oY * a + *tY * (1 - a);
813 *tU = *oU * a + *tU * (1 - a);
814 *tV = *oV * a + *tV * (1 - a);
831 throw PixelFormatError ("alpha_blend()", _pixel_format);
836 Image::copy (shared_ptr<const Image> other, Position<int> position)
838 /* Only implemented for RGB24 onto RGB24 so far */
839 DCPOMATIC_ASSERT (_pixel_format == AV_PIX_FMT_RGB24 && other->pixel_format() == AV_PIX_FMT_RGB24);
840 DCPOMATIC_ASSERT (position.x >= 0 && position.y >= 0);
842 int const N = min (position.x + other->size().width, size().width) - position.x;
843 for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
844 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
845 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
846 memcpy (tp, op, N * 3);
851 Image::read_from_socket (shared_ptr<Socket> socket)
853 for (int i = 0; i < planes(); ++i) {
854 uint8_t* p = data()[i];
855 int const lines = sample_size(i).height;
856 for (int y = 0; y < lines; ++y) {
857 socket->read (p, line_size()[i]);
864 Image::write_to_socket (shared_ptr<Socket> socket) const
866 for (int i = 0; i < planes(); ++i) {
867 uint8_t* p = data()[i];
868 int const lines = sample_size(i).height;
869 for (int y = 0; y < lines; ++y) {
870 socket->write (p, line_size()[i]);
877 Image::bytes_per_pixel (int c) const
879 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
881 throw PixelFormatError ("bytes_per_pixel()", _pixel_format);
888 float bpp[4] = { 0, 0, 0, 0 };
890 #ifdef DCPOMATIC_HAVE_AVCOMPONENTDESCRIPTOR_DEPTH_MINUS1
891 bpp[0] = floor ((d->comp[0].depth_minus1 + 8) / 8);
892 if (d->nb_components > 1) {
893 bpp[1] = floor ((d->comp[1].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
895 if (d->nb_components > 2) {
896 bpp[2] = floor ((d->comp[2].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
898 if (d->nb_components > 3) {
899 bpp[3] = floor ((d->comp[3].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
902 bpp[0] = floor ((d->comp[0].depth + 7) / 8);
903 if (d->nb_components > 1) {
904 bpp[1] = floor ((d->comp[1].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
906 if (d->nb_components > 2) {
907 bpp[2] = floor ((d->comp[2].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
909 if (d->nb_components > 3) {
910 bpp[3] = floor ((d->comp[3].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
914 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
915 /* Not planar; sum them up */
916 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
922 /** Construct a Image of a given size and format, allocating memory
925 * @param p Pixel format.
926 * @param s Size in pixels.
927 * @param aligned true to make each row of this image aligned to a ALIGNMENT-byte boundary.
929 Image::Image (AVPixelFormat p, dcp::Size s, bool aligned)
940 _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
941 _data[0] = _data[1] = _data[2] = _data[3] = 0;
943 _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
944 _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
946 _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
947 _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
949 for (int i = 0; i < planes(); ++i) {
950 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
951 _stride[i] = stride_round_up (i, _line_size, _aligned ? ALIGNMENT : 1);
953 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
954 uses a 16-byte fetch to read three bytes (R/G/B) of image data.
955 Hence on the last pixel of the last line it reads over the end of
956 the actual data by 1 byte. If the width of an image is a multiple
957 of the stride alignment there will be no padding at the end of image lines.
958 OS X crashes on this illegal read, though other operating systems don't
959 seem to mind. The nasty + 1 in this malloc makes sure there is always a byte
960 for that instruction to read safely.
962 Further to the above, valgrind is now telling me that ff_rgb24ToY_ssse3
963 over-reads by more then _avx. I can't follow the code to work out how much,
964 so I'll just over-allocate by ALIGNMENT bytes and have done with it. Empirical
965 testing suggests that it works.
967 In addition to these concerns, we may read/write as much as a whole extra line
968 at the end of each plane in cases where we are messing with offsets in order to
969 do pad or crop. To solve this we over-allocate by an extra _stride[i] bytes.
971 As an example: we may write to images starting at an offset so we get some padding.
972 Hence we want to write in the following pattern:
974 block start write start line end
975 |..(padding)..|<------line-size------------->|..(padding)..|
976 |..(padding)..|<------line-size------------->|..(padding)..|
977 |..(padding)..|<------line-size------------->|..(padding)..|
979 where line-size is of the smaller (inter_size) image and the full padded line length is that of
980 out_size. To get things to work we have to tell FFmpeg that the stride is that of out_size.
981 However some parts of FFmpeg (notably rgb48Toxyz12 in swscale.c) process data for the full
982 specified *stride*. This does not matter until we get to the last line:
984 block start write start line end
985 |..(padding)..|<------line-size------------->|XXXwrittenXXX|
986 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXX|
987 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXXXXXwrittenXXX
990 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * (sample_size(i).height + 1) + ALIGNMENT);
991 #if HAVE_VALGRIND_MEMCHECK_H
992 /* The data between the end of the line size and the stride is undefined but processed by
993 libswscale, causing lots of valgrind errors. Mark it all defined to quell these errors.
995 VALGRIND_MAKE_MEM_DEFINED (_data[i], _stride[i] * (sample_size(i).height + 1) + ALIGNMENT);
1000 Image::Image (Image const & other)
1001 : boost::enable_shared_from_this<Image>(other)
1002 , _size (other._size)
1003 , _pixel_format (other._pixel_format)
1004 , _aligned (other._aligned)
1008 for (int i = 0; i < planes(); ++i) {
1009 uint8_t* p = _data[i];
1010 uint8_t* q = other._data[i];
1011 int const lines = sample_size(i).height;
1012 for (int j = 0; j < lines; ++j) {
1013 memcpy (p, q, _line_size[i]);
1015 q += other.stride()[i];
1020 Image::Image (AVFrame* frame)
1021 : _size (frame->width, frame->height)
1022 , _pixel_format (static_cast<AVPixelFormat> (frame->format))
1027 for (int i = 0; i < planes(); ++i) {
1028 uint8_t* p = _data[i];
1029 uint8_t* q = frame->data[i];
1030 int const lines = sample_size(i).height;
1031 for (int j = 0; j < lines; ++j) {
1032 memcpy (p, q, _line_size[i]);
1034 /* AVFrame's linesize is what we call `stride' */
1035 q += frame->linesize[i];
1040 Image::Image (shared_ptr<const Image> other, bool aligned)
1041 : _size (other->_size)
1042 , _pixel_format (other->_pixel_format)
1043 , _aligned (aligned)
1047 for (int i = 0; i < planes(); ++i) {
1048 DCPOMATIC_ASSERT (line_size()[i] == other->line_size()[i]);
1049 uint8_t* p = _data[i];
1050 uint8_t* q = other->data()[i];
1051 int const lines = sample_size(i).height;
1052 for (int j = 0; j < lines; ++j) {
1053 memcpy (p, q, line_size()[i]);
1055 q += other->stride()[i];
1061 Image::operator= (Image const & other)
1063 if (this == &other) {
1073 Image::swap (Image & other)
1075 std::swap (_size, other._size);
1076 std::swap (_pixel_format, other._pixel_format);
1078 for (int i = 0; i < 4; ++i) {
1079 std::swap (_data[i], other._data[i]);
1080 std::swap (_line_size[i], other._line_size[i]);
1081 std::swap (_stride[i], other._stride[i]);
1084 std::swap (_aligned, other._aligned);
1087 /** Destroy a Image */
1090 for (int i = 0; i < planes(); ++i) {
1095 av_free (_line_size);
1100 Image::data () const
1106 Image::line_size () const
1112 Image::stride () const
1118 Image::size () const
1124 Image::aligned () const
1130 merge (list<PositionImage> images)
1132 if (images.empty ()) {
1133 return PositionImage ();
1136 if (images.size() == 1) {
1137 return images.front ();
1140 dcpomatic::Rect<int> all (images.front().position, images.front().image->size().width, images.front().image->size().height);
1141 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1142 all.extend (dcpomatic::Rect<int> (i->position, i->image->size().width, i->image->size().height));
1145 shared_ptr<Image> merged (new Image (images.front().image->pixel_format (), dcp::Size (all.width, all.height), true));
1146 merged->make_transparent ();
1147 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1148 merged->alpha_blend (i->image, i->position - all.position());
1151 return PositionImage (merged, all.position ());
1155 operator== (Image const & a, Image const & b)
1157 if (a.planes() != b.planes() || a.pixel_format() != b.pixel_format() || a.aligned() != b.aligned()) {
1161 for (int c = 0; c < a.planes(); ++c) {
1162 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]) {
1166 uint8_t* p = a.data()[c];
1167 uint8_t* q = b.data()[c];
1168 int const lines = a.sample_size(c).height;
1169 for (int y = 0; y < lines; ++y) {
1170 if (memcmp (p, q, a.line_size()[c]) != 0) {
1183 * @param f Amount to fade by; 0 is black, 1 is no fade.
1186 Image::fade (float f)
1188 /* U/V black value for 8-bit colour */
1189 static int const eight_bit_uv = (1 << 7) - 1;
1190 /* U/V black value for 10-bit colour */
1191 static uint16_t const ten_bit_uv = (1 << 9) - 1;
1193 switch (_pixel_format) {
1194 case AV_PIX_FMT_YUV420P:
1197 uint8_t* p = data()[0];
1198 int const lines = sample_size(0).height;
1199 for (int y = 0; y < lines; ++y) {
1201 for (int x = 0; x < line_size()[0]; ++x) {
1202 *q = int(float(*q) * f);
1209 for (int c = 1; c < 3; ++c) {
1210 uint8_t* p = data()[c];
1211 int const lines = sample_size(c).height;
1212 for (int y = 0; y < lines; ++y) {
1214 for (int x = 0; x < line_size()[c]; ++x) {
1215 *q = eight_bit_uv + int((int(*q) - eight_bit_uv) * f);
1225 case AV_PIX_FMT_RGB24:
1228 uint8_t* p = data()[0];
1229 int const lines = sample_size(0).height;
1230 for (int y = 0; y < lines; ++y) {
1232 for (int x = 0; x < line_size()[0]; ++x) {
1233 *q = int (float (*q) * f);
1241 case AV_PIX_FMT_XYZ12LE:
1242 case AV_PIX_FMT_RGB48LE:
1243 /* 16-bit little-endian */
1244 for (int c = 0; c < 3; ++c) {
1245 int const stride_pixels = stride()[c] / 2;
1246 int const line_size_pixels = line_size()[c] / 2;
1247 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1248 int const lines = sample_size(c).height;
1249 for (int y = 0; y < lines; ++y) {
1251 for (int x = 0; x < line_size_pixels; ++x) {
1252 *q = int (float (*q) * f);
1260 case AV_PIX_FMT_YUV422P10LE:
1264 int const stride_pixels = stride()[0] / 2;
1265 int const line_size_pixels = line_size()[0] / 2;
1266 uint16_t* p = reinterpret_cast<uint16_t*> (data()[0]);
1267 int const lines = sample_size(0).height;
1268 for (int y = 0; y < lines; ++y) {
1270 for (int x = 0; x < line_size_pixels; ++x) {
1271 *q = int(float(*q) * f);
1279 for (int c = 1; c < 3; ++c) {
1280 int const stride_pixels = stride()[c] / 2;
1281 int const line_size_pixels = line_size()[c] / 2;
1282 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1283 int const lines = sample_size(c).height;
1284 for (int y = 0; y < lines; ++y) {
1286 for (int x = 0; x < line_size_pixels; ++x) {
1287 *q = ten_bit_uv + int((int(*q) - ten_bit_uv) * f);
1298 throw PixelFormatError ("fade()", _pixel_format);
1302 shared_ptr<const Image>
1303 Image::ensure_aligned (shared_ptr<const Image> image)
1305 if (image->aligned()) {
1309 return shared_ptr<Image> (new Image (image, true));
1313 Image::memory_used () const
1316 for (int i = 0; i < planes(); ++i) {
1317 m += _stride[i] * sample_size(i).height;
1340 png_write_data (png_structp png_ptr, png_bytep data, png_size_t length)
1342 Memory* mem = reinterpret_cast<Memory*>(png_get_io_ptr(png_ptr));
1343 size_t size = mem->size + length;
1346 mem->data = reinterpret_cast<uint8_t*>(realloc(mem->data, size));
1348 mem->data = reinterpret_cast<uint8_t*>(malloc(size));
1352 throw EncodeError (N_("could not allocate memory for PNG"));
1355 memcpy (mem->data + mem->size, data, length);
1356 mem->size += length;
1360 png_flush (png_structp)
1366 png_error_fn (png_structp png_ptr, char const * message)
1368 reinterpret_cast<Image*>(png_get_error_ptr(png_ptr))->png_error (message);
1372 Image::png_error (char const * message)
1374 throw EncodeError (String::compose ("Error during PNG write: %1", message));
1378 Image::as_png () const
1380 DCPOMATIC_ASSERT (bytes_per_pixel(0) == 4);
1381 DCPOMATIC_ASSERT (planes() == 1);
1382 if (pixel_format() != AV_PIX_FMT_RGBA) {
1383 return convert_pixel_format(dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_RGBA, true, false)->as_png();
1386 /* error handling? */
1387 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, reinterpret_cast<void*>(const_cast<Image*>(this)), png_error_fn, 0);
1389 throw EncodeError (N_("could not create PNG write struct"));
1394 png_set_write_fn (png_ptr, &state, png_write_data, png_flush);
1396 png_infop info_ptr = png_create_info_struct(png_ptr);
1398 png_destroy_write_struct (&png_ptr, &info_ptr);
1399 throw EncodeError (N_("could not create PNG info struct"));
1402 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);
1404 png_byte ** row_pointers = reinterpret_cast<png_byte **>(png_malloc(png_ptr, size().height * sizeof(png_byte *)));
1405 for (int i = 0; i < size().height; ++i) {
1406 row_pointers[i] = (png_byte *) (data()[0] + i * stride()[0]);
1409 png_write_info (png_ptr, info_ptr);
1410 png_write_image (png_ptr, row_pointers);
1411 png_write_end (png_ptr, info_ptr);
1413 png_destroy_write_struct (&png_ptr, &info_ptr);
1414 png_free (png_ptr, row_pointers);
1416 return dcp::Data (state.data, state.size);