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