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 /* Here's an image of out_size. Below we may write to it starting at an offset so we get some padding.
144 Hence we want to write in the following pattern:
146 block start write start line end
147 |..(padding)..|<------line-size------------->|..(padding)..|
148 |..(padding)..|<------line-size------------->|..(padding)..|
149 |..(padding)..|<------line-size------------->|..(padding)..|
151 where line-size is of the smaller (inter_size) image and the full padded line length is that of
152 out_size. To get things to work we have to tell FFmpeg that the stride is that of out_size.
153 However some parts of FFmpeg (notably rgb48Toxyz12 in swscale.c) process data for the full
154 specified *stride*. This does not matter until we get to the last line:
156 block start write start line end
157 |..(padding)..|<------line-size------------->|XXXwrittenXXX|
158 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXX|
159 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXXXXXwrittenXXX
162 To get around this, we ask Image to overallocate its buffers by the overrun.
165 shared_ptr<Image> out (new Image (out_format, out_size, out_aligned, (out_size.width - inter_size.width) / 2));
168 /* Size of the image after any crop */
169 dcp::Size const cropped_size = crop.apply (size ());
171 /* Scale context for a scale from cropped_size to inter_size */
172 struct SwsContext* scale_context = sws_getContext (
173 cropped_size.width, cropped_size.height, pixel_format(),
174 inter_size.width, inter_size.height, out_format,
175 fast ? SWS_FAST_BILINEAR : SWS_BICUBIC, 0, 0, 0
178 if (!scale_context) {
179 throw runtime_error (N_("Could not allocate SwsContext"));
182 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
183 int const lut[dcp::YUV_TO_RGB_COUNT] = {
188 /* The 3rd parameter here is:
189 0 -> source range MPEG (i.e. "video", 16-235)
190 1 -> source range JPEG (i.e. "full", 0-255)
192 0 -> destination range MPEG (i.e. "video", 16-235)
193 1 -> destination range JPEG (i.e. "full", 0-255)
195 But remember: sws_setColorspaceDetails ignores these
196 parameters unless the corresponding image isYUV or isGray.
197 (If it's neither, it uses video range).
199 sws_setColorspaceDetails (
201 sws_getCoefficients (lut[yuv_to_rgb]), video_range == VIDEO_RANGE_VIDEO ? 0 : 1,
202 sws_getCoefficients (lut[yuv_to_rgb]), 1,
206 AVPixFmtDescriptor const * in_desc = av_pix_fmt_desc_get (_pixel_format);
208 throw PixelFormatError ("crop_scale_window()", _pixel_format);
211 /* Prepare input data pointers with crop */
212 uint8_t* scale_in_data[planes()];
213 for (int c = 0; c < planes(); ++c) {
214 /* To work out the crop in bytes, start by multiplying
215 the crop by the (average) bytes per pixel. Then
216 round down so that we don't crop a subsampled pixel until
217 we've cropped all of its Y-channel pixels.
219 int const x = lrintf (bytes_per_pixel(c) * crop.left) & ~ ((int) in_desc->log2_chroma_w);
220 scale_in_data[c] = data()[c] + x + stride()[c] * (crop.top / vertical_factor(c));
223 /* Corner of the image within out_size */
224 Position<int> const corner ((out_size.width - inter_size.width) / 2, (out_size.height - inter_size.height) / 2);
226 AVPixFmtDescriptor const * out_desc = av_pix_fmt_desc_get (out_format);
228 throw PixelFormatError ("crop_scale_window()", out_format);
231 uint8_t* scale_out_data[out->planes()];
232 for (int c = 0; c < out->planes(); ++c) {
233 /* See the note in the crop loop above */
234 int const x = lrintf (out->bytes_per_pixel(c) * corner.x) & ~ ((int) out_desc->log2_chroma_w);
235 scale_out_data[c] = out->data()[c] + x + out->stride()[c] * (corner.y / out->vertical_factor(c));
240 scale_in_data, stride(),
241 0, cropped_size.height,
242 scale_out_data, out->stride()
245 sws_freeContext (scale_context);
251 Image::convert_pixel_format (dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
253 return scale(size(), yuv_to_rgb, out_format, out_aligned, fast);
256 /** @param out_size Size to scale to.
257 * @param yuv_to_rgb YUVToRGB transform transform to use, if required.
258 * @param out_format Output pixel format.
259 * @param out_aligned true to make an aligned output image.
260 * @param fast Try to be fast at the possible expense of quality; at present this means using
261 * fast bilinear rather than bicubic scaling.
264 Image::scale (dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
266 /* Empirical testing suggests that sws_scale() will crash if
267 the input image is not aligned.
269 DCPOMATIC_ASSERT (aligned ());
271 shared_ptr<Image> scaled (new Image (out_format, out_size, out_aligned));
273 struct SwsContext* scale_context = sws_getContext (
274 size().width, size().height, pixel_format(),
275 out_size.width, out_size.height, out_format,
276 (fast ? SWS_FAST_BILINEAR : SWS_BICUBIC) | SWS_ACCURATE_RND, 0, 0, 0
279 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
280 int const lut[dcp::YUV_TO_RGB_COUNT] = {
285 /* The 3rd parameter here is:
286 0 -> source range MPEG (i.e. "video", 16-235)
287 1 -> source range JPEG (i.e. "full", 0-255)
289 0 -> destination range MPEG (i.e. "video", 16-235)
290 1 -> destination range JPEG (i.e. "full", 0-255)
292 But remember: sws_setColorspaceDetails ignores these
293 parameters unless the corresponding image isYUV or isGray.
294 (If it's neither, it uses video range).
296 sws_setColorspaceDetails (
298 sws_getCoefficients (lut[yuv_to_rgb]), 0,
299 sws_getCoefficients (lut[yuv_to_rgb]), 0,
307 scaled->data(), scaled->stride()
310 sws_freeContext (scale_context);
315 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
317 Image::yuv_16_black (uint16_t v, bool alpha)
319 memset (data()[0], 0, sample_size(0).height * stride()[0]);
320 for (int i = 1; i < 3; ++i) {
321 int16_t* p = reinterpret_cast<int16_t*> (data()[i]);
322 int const lines = sample_size(i).height;
323 for (int y = 0; y < lines; ++y) {
324 /* We divide by 2 here because we are writing 2 bytes at a time */
325 for (int x = 0; x < line_size()[i] / 2; ++x) {
328 p += stride()[i] / 2;
333 memset (data()[3], 0, sample_size(3).height * stride()[3]);
338 Image::swap_16 (uint16_t v)
340 return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
346 /* U/V black value for 8-bit colour */
347 static uint8_t const eight_bit_uv = (1 << 7) - 1;
348 /* U/V black value for 9-bit colour */
349 static uint16_t const nine_bit_uv = (1 << 8) - 1;
350 /* U/V black value for 10-bit colour */
351 static uint16_t const ten_bit_uv = (1 << 9) - 1;
352 /* U/V black value for 16-bit colour */
353 static uint16_t const sixteen_bit_uv = (1 << 15) - 1;
355 switch (_pixel_format) {
356 case AV_PIX_FMT_YUV420P:
357 case AV_PIX_FMT_YUV422P:
358 case AV_PIX_FMT_YUV444P:
359 case AV_PIX_FMT_YUV411P:
360 memset (data()[0], 0, sample_size(0).height * stride()[0]);
361 memset (data()[1], eight_bit_uv, sample_size(1).height * stride()[1]);
362 memset (data()[2], eight_bit_uv, sample_size(2).height * stride()[2]);
365 case AV_PIX_FMT_YUVJ420P:
366 case AV_PIX_FMT_YUVJ422P:
367 case AV_PIX_FMT_YUVJ444P:
368 memset (data()[0], 0, sample_size(0).height * stride()[0]);
369 memset (data()[1], eight_bit_uv + 1, sample_size(1).height * stride()[1]);
370 memset (data()[2], eight_bit_uv + 1, sample_size(2).height * stride()[2]);
373 case AV_PIX_FMT_YUV422P9LE:
374 case AV_PIX_FMT_YUV444P9LE:
375 yuv_16_black (nine_bit_uv, false);
378 case AV_PIX_FMT_YUV422P9BE:
379 case AV_PIX_FMT_YUV444P9BE:
380 yuv_16_black (swap_16 (nine_bit_uv), false);
383 case AV_PIX_FMT_YUV422P10LE:
384 case AV_PIX_FMT_YUV444P10LE:
385 yuv_16_black (ten_bit_uv, false);
388 case AV_PIX_FMT_YUV422P16LE:
389 case AV_PIX_FMT_YUV444P16LE:
390 yuv_16_black (sixteen_bit_uv, false);
393 case AV_PIX_FMT_YUV444P10BE:
394 case AV_PIX_FMT_YUV422P10BE:
395 yuv_16_black (swap_16 (ten_bit_uv), false);
398 case AV_PIX_FMT_YUVA420P9BE:
399 case AV_PIX_FMT_YUVA422P9BE:
400 case AV_PIX_FMT_YUVA444P9BE:
401 yuv_16_black (swap_16 (nine_bit_uv), true);
404 case AV_PIX_FMT_YUVA420P9LE:
405 case AV_PIX_FMT_YUVA422P9LE:
406 case AV_PIX_FMT_YUVA444P9LE:
407 yuv_16_black (nine_bit_uv, true);
410 case AV_PIX_FMT_YUVA420P10BE:
411 case AV_PIX_FMT_YUVA422P10BE:
412 case AV_PIX_FMT_YUVA444P10BE:
413 yuv_16_black (swap_16 (ten_bit_uv), true);
416 case AV_PIX_FMT_YUVA420P10LE:
417 case AV_PIX_FMT_YUVA422P10LE:
418 case AV_PIX_FMT_YUVA444P10LE:
419 yuv_16_black (ten_bit_uv, true);
422 case AV_PIX_FMT_YUVA420P16BE:
423 case AV_PIX_FMT_YUVA422P16BE:
424 case AV_PIX_FMT_YUVA444P16BE:
425 yuv_16_black (swap_16 (sixteen_bit_uv), true);
428 case AV_PIX_FMT_YUVA420P16LE:
429 case AV_PIX_FMT_YUVA422P16LE:
430 case AV_PIX_FMT_YUVA444P16LE:
431 yuv_16_black (sixteen_bit_uv, true);
434 case AV_PIX_FMT_RGB24:
435 case AV_PIX_FMT_ARGB:
436 case AV_PIX_FMT_RGBA:
437 case AV_PIX_FMT_ABGR:
438 case AV_PIX_FMT_BGRA:
439 case AV_PIX_FMT_RGB555LE:
440 case AV_PIX_FMT_RGB48LE:
441 case AV_PIX_FMT_RGB48BE:
442 case AV_PIX_FMT_XYZ12LE:
443 memset (data()[0], 0, sample_size(0).height * stride()[0]);
446 case AV_PIX_FMT_UYVY422:
448 int const Y = sample_size(0).height;
449 int const X = line_size()[0];
450 uint8_t* p = data()[0];
451 for (int y = 0; y < Y; ++y) {
452 for (int x = 0; x < X / 4; ++x) {
453 *p++ = eight_bit_uv; // Cb
455 *p++ = eight_bit_uv; // Cr
463 throw PixelFormatError ("make_black()", _pixel_format);
468 Image::make_transparent ()
470 if (_pixel_format != AV_PIX_FMT_BGRA && _pixel_format != AV_PIX_FMT_RGBA) {
471 throw PixelFormatError ("make_transparent()", _pixel_format);
474 memset (data()[0], 0, sample_size(0).height * stride()[0]);
478 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
480 /* We're blending RGBA or BGRA images */
481 DCPOMATIC_ASSERT (other->pixel_format() == AV_PIX_FMT_BGRA || other->pixel_format() == AV_PIX_FMT_RGBA);
482 int const blue = other->pixel_format() == AV_PIX_FMT_BGRA ? 0 : 2;
483 int const red = other->pixel_format() == AV_PIX_FMT_BGRA ? 2 : 0;
485 int const other_bpp = 4;
487 int start_tx = position.x;
491 start_ox = -start_tx;
495 int start_ty = position.y;
499 start_oy = -start_ty;
503 switch (_pixel_format) {
504 case AV_PIX_FMT_RGB24:
506 /* Going onto RGB24. First byte is red, second green, third blue */
507 int const this_bpp = 3;
508 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
509 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
510 uint8_t* op = other->data()[0] + oy * other->stride()[0];
511 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
512 float const alpha = float (op[3]) / 255;
513 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
514 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
515 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
523 case AV_PIX_FMT_BGRA:
525 int const this_bpp = 4;
526 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
527 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
528 uint8_t* op = other->data()[0] + oy * other->stride()[0];
529 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
530 float const alpha = float (op[3]) / 255;
531 tp[0] = op[blue] * alpha + tp[0] * (1 - alpha);
532 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
533 tp[2] = op[red] * alpha + tp[2] * (1 - alpha);
534 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
542 case AV_PIX_FMT_RGBA:
544 int const this_bpp = 4;
545 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
546 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
547 uint8_t* op = other->data()[0] + oy * other->stride()[0];
548 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
549 float const alpha = float (op[3]) / 255;
550 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
551 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
552 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
553 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
561 case AV_PIX_FMT_RGB48LE:
563 int const this_bpp = 6;
564 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
565 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
566 uint8_t* op = other->data()[0] + oy * other->stride()[0];
567 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
568 float const alpha = float (op[3]) / 255;
569 /* Blend high bytes */
570 tp[1] = op[red] * alpha + tp[1] * (1 - alpha);
571 tp[3] = op[1] * alpha + tp[3] * (1 - alpha);
572 tp[5] = op[blue] * alpha + tp[5] * (1 - alpha);
580 case AV_PIX_FMT_XYZ12LE:
582 dcp::ColourConversion conv = dcp::ColourConversion::srgb_to_xyz();
583 double fast_matrix[9];
584 dcp::combined_rgb_to_xyz (conv, fast_matrix);
585 double const * lut_in = conv.in()->lut (8, false);
586 double const * lut_out = conv.out()->lut (16, true);
587 int const this_bpp = 6;
588 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
589 uint16_t* tp = reinterpret_cast<uint16_t*> (data()[0] + ty * stride()[0] + start_tx * this_bpp);
590 uint8_t* op = other->data()[0] + oy * other->stride()[0];
591 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
592 float const alpha = float (op[3]) / 255;
594 /* Convert sRGB to XYZ; op is BGRA. First, input gamma LUT */
595 double const r = lut_in[op[red]];
596 double const g = lut_in[op[1]];
597 double const b = lut_in[op[blue]];
599 /* RGB to XYZ, including Bradford transform and DCI companding */
600 double const x = max (0.0, min (65535.0, r * fast_matrix[0] + g * fast_matrix[1] + b * fast_matrix[2]));
601 double const y = max (0.0, min (65535.0, r * fast_matrix[3] + g * fast_matrix[4] + b * fast_matrix[5]));
602 double const z = max (0.0, min (65535.0, r * fast_matrix[6] + g * fast_matrix[7] + b * fast_matrix[8]));
604 /* Out gamma LUT and blend */
605 tp[0] = lrint(lut_out[lrint(x)] * 65535) * alpha + tp[0] * (1 - alpha);
606 tp[1] = lrint(lut_out[lrint(y)] * 65535) * alpha + tp[1] * (1 - alpha);
607 tp[2] = lrint(lut_out[lrint(z)] * 65535) * alpha + tp[2] * (1 - alpha);
615 case AV_PIX_FMT_YUV420P:
617 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
618 dcp::Size const ts = size();
619 dcp::Size const os = yuv->size();
620 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
621 int const hty = ty / 2;
622 int const hoy = oy / 2;
623 uint8_t* tY = data()[0] + (ty * stride()[0]) + start_tx;
624 uint8_t* tU = data()[1] + (hty * stride()[1]) + start_tx / 2;
625 uint8_t* tV = data()[2] + (hty * stride()[2]) + start_tx / 2;
626 uint8_t* oY = yuv->data()[0] + (oy * yuv->stride()[0]) + start_ox;
627 uint8_t* oU = yuv->data()[1] + (hoy * yuv->stride()[1]) + start_ox / 2;
628 uint8_t* oV = yuv->data()[2] + (hoy * yuv->stride()[2]) + start_ox / 2;
629 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
630 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
631 float const a = float(alpha[3]) / 255;
632 *tY = *oY * a + *tY * (1 - a);
633 *tU = *oU * a + *tU * (1 - a);
634 *tV = *oV * a + *tV * (1 - a);
650 case AV_PIX_FMT_YUV420P10:
652 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
653 dcp::Size const ts = size();
654 dcp::Size const os = yuv->size();
655 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
656 int const hty = ty / 2;
657 int const hoy = oy / 2;
658 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
659 uint16_t* tU = ((uint16_t *) (data()[1] + (hty * stride()[1]))) + start_tx / 2;
660 uint16_t* tV = ((uint16_t *) (data()[2] + (hty * stride()[2]))) + start_tx / 2;
661 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
662 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (hoy * yuv->stride()[1]))) + start_ox / 2;
663 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (hoy * yuv->stride()[2]))) + start_ox / 2;
664 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
665 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
666 float const a = float(alpha[3]) / 255;
667 *tY = *oY * a + *tY * (1 - a);
668 *tU = *oU * a + *tU * (1 - a);
669 *tV = *oV * a + *tV * (1 - a);
685 case AV_PIX_FMT_YUV422P10LE:
687 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
688 dcp::Size const ts = size();
689 dcp::Size const os = yuv->size();
690 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
691 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
692 uint16_t* tU = ((uint16_t *) (data()[1] + (ty * stride()[1]))) + start_tx / 2;
693 uint16_t* tV = ((uint16_t *) (data()[2] + (ty * stride()[2]))) + start_tx / 2;
694 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
695 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (oy * yuv->stride()[1]))) + start_ox / 2;
696 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (oy * yuv->stride()[2]))) + start_ox / 2;
697 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
698 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
699 float const a = float(alpha[3]) / 255;
700 *tY = *oY * a + *tY * (1 - a);
701 *tU = *oU * a + *tU * (1 - a);
702 *tV = *oV * a + *tV * (1 - a);
719 throw PixelFormatError ("alpha_blend()", _pixel_format);
724 Image::copy (shared_ptr<const Image> other, Position<int> position)
726 /* Only implemented for RGB24 onto RGB24 so far */
727 DCPOMATIC_ASSERT (_pixel_format == AV_PIX_FMT_RGB24 && other->pixel_format() == AV_PIX_FMT_RGB24);
728 DCPOMATIC_ASSERT (position.x >= 0 && position.y >= 0);
730 int const N = min (position.x + other->size().width, size().width) - position.x;
731 for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
732 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
733 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
734 memcpy (tp, op, N * 3);
739 Image::read_from_socket (shared_ptr<Socket> socket)
741 for (int i = 0; i < planes(); ++i) {
742 uint8_t* p = data()[i];
743 int const lines = sample_size(i).height;
744 for (int y = 0; y < lines; ++y) {
745 socket->read (p, line_size()[i]);
752 Image::write_to_socket (shared_ptr<Socket> socket) const
754 for (int i = 0; i < planes(); ++i) {
755 uint8_t* p = data()[i];
756 int const lines = sample_size(i).height;
757 for (int y = 0; y < lines; ++y) {
758 socket->write (p, line_size()[i]);
765 Image::bytes_per_pixel (int c) const
767 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
769 throw PixelFormatError ("bytes_per_pixel()", _pixel_format);
776 float bpp[4] = { 0, 0, 0, 0 };
778 #ifdef DCPOMATIC_HAVE_AVCOMPONENTDESCRIPTOR_DEPTH_MINUS1
779 bpp[0] = floor ((d->comp[0].depth_minus1 + 8) / 8);
780 if (d->nb_components > 1) {
781 bpp[1] = floor ((d->comp[1].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
783 if (d->nb_components > 2) {
784 bpp[2] = floor ((d->comp[2].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
786 if (d->nb_components > 3) {
787 bpp[3] = floor ((d->comp[3].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
790 bpp[0] = floor ((d->comp[0].depth + 7) / 8);
791 if (d->nb_components > 1) {
792 bpp[1] = floor ((d->comp[1].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
794 if (d->nb_components > 2) {
795 bpp[2] = floor ((d->comp[2].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
797 if (d->nb_components > 3) {
798 bpp[3] = floor ((d->comp[3].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
802 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
803 /* Not planar; sum them up */
804 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
810 /** Construct a Image of a given size and format, allocating memory
813 * @param p Pixel format.
814 * @param s Size in pixels.
815 * @param aligned true to make each row of this image aligned to a 32-byte boundary.
816 * @param extra_pixels Amount of extra "run-off" memory to allocate at the end of each plane in pixels.
818 Image::Image (AVPixelFormat p, dcp::Size s, bool aligned, int extra_pixels)
822 , _extra_pixels (extra_pixels)
830 _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
831 _data[0] = _data[1] = _data[2] = _data[3] = 0;
833 _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
834 _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
836 _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
837 _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
839 for (int i = 0; i < planes(); ++i) {
840 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
841 _stride[i] = stride_round_up (i, _line_size, _aligned ? 32 : 1);
843 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
844 uses a 16-byte fetch to read three bytes (R/G/B) of image data.
845 Hence on the last pixel of the last line it reads over the end of
846 the actual data by 1 byte. If the width of an image is a multiple
847 of the stride alignment there will be no padding at the end of image lines.
848 OS X crashes on this illegal read, though other operating systems don't
849 seem to mind. The nasty + 1 in this malloc makes sure there is always a byte
850 for that instruction to read safely.
852 Further to the above, valgrind is now telling me that ff_rgb24ToY_ssse3
853 over-reads by more then _avx. I can't follow the code to work out how much,
854 so I'll just over-allocate by 32 bytes and have done with it. Empirical
855 testing suggests that it works.
857 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * sample_size(i).height + _extra_pixels * bytes_per_pixel(i) + 32);
858 #if HAVE_VALGRIND_MEMCHECK_H
859 /* The data between the end of the line size and the stride is undefined but processed by
860 libswscale, causing lots of valgrind errors. Mark it all defined to quell these errors.
862 VALGRIND_MAKE_MEM_DEFINED (_data[i], _stride[i] * sample_size(i).height + _extra_pixels * bytes_per_pixel(i) + 32);
867 Image::Image (Image const & other)
868 : boost::enable_shared_from_this<Image>(other)
869 , _size (other._size)
870 , _pixel_format (other._pixel_format)
871 , _aligned (other._aligned)
872 , _extra_pixels (other._extra_pixels)
876 for (int i = 0; i < planes(); ++i) {
877 uint8_t* p = _data[i];
878 uint8_t* q = other._data[i];
879 int const lines = sample_size(i).height;
880 for (int j = 0; j < lines; ++j) {
881 memcpy (p, q, _line_size[i]);
883 q += other.stride()[i];
888 Image::Image (AVFrame* frame)
889 : _size (frame->width, frame->height)
890 , _pixel_format (static_cast<AVPixelFormat> (frame->format))
896 for (int i = 0; i < planes(); ++i) {
897 uint8_t* p = _data[i];
898 uint8_t* q = frame->data[i];
899 int const lines = sample_size(i).height;
900 for (int j = 0; j < lines; ++j) {
901 memcpy (p, q, _line_size[i]);
903 /* AVFrame's linesize is what we call `stride' */
904 q += frame->linesize[i];
909 Image::Image (shared_ptr<const Image> other, bool aligned)
910 : _size (other->_size)
911 , _pixel_format (other->_pixel_format)
913 , _extra_pixels (other->_extra_pixels)
917 for (int i = 0; i < planes(); ++i) {
918 DCPOMATIC_ASSERT (line_size()[i] == other->line_size()[i]);
919 uint8_t* p = _data[i];
920 uint8_t* q = other->data()[i];
921 int const lines = sample_size(i).height;
922 for (int j = 0; j < lines; ++j) {
923 memcpy (p, q, line_size()[i]);
925 q += other->stride()[i];
931 Image::operator= (Image const & other)
933 if (this == &other) {
943 Image::swap (Image & other)
945 std::swap (_size, other._size);
946 std::swap (_pixel_format, other._pixel_format);
948 for (int i = 0; i < 4; ++i) {
949 std::swap (_data[i], other._data[i]);
950 std::swap (_line_size[i], other._line_size[i]);
951 std::swap (_stride[i], other._stride[i]);
954 std::swap (_aligned, other._aligned);
955 std::swap (_extra_pixels, other._extra_pixels);
958 /** Destroy a Image */
961 for (int i = 0; i < planes(); ++i) {
966 av_free (_line_size);
977 Image::line_size () const
983 Image::stride () const
995 Image::aligned () const
1001 merge (list<PositionImage> images)
1003 if (images.empty ()) {
1004 return PositionImage ();
1007 if (images.size() == 1) {
1008 return images.front ();
1011 dcpomatic::Rect<int> all (images.front().position, images.front().image->size().width, images.front().image->size().height);
1012 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1013 all.extend (dcpomatic::Rect<int> (i->position, i->image->size().width, i->image->size().height));
1016 shared_ptr<Image> merged (new Image (images.front().image->pixel_format (), dcp::Size (all.width, all.height), true));
1017 merged->make_transparent ();
1018 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1019 merged->alpha_blend (i->image, i->position - all.position());
1022 return PositionImage (merged, all.position ());
1026 operator== (Image const & a, Image const & b)
1028 if (a.planes() != b.planes() || a.pixel_format() != b.pixel_format() || a.aligned() != b.aligned()) {
1032 for (int c = 0; c < a.planes(); ++c) {
1033 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]) {
1037 uint8_t* p = a.data()[c];
1038 uint8_t* q = b.data()[c];
1039 int const lines = a.sample_size(c).height;
1040 for (int y = 0; y < lines; ++y) {
1041 if (memcmp (p, q, a.line_size()[c]) != 0) {
1054 * @param f Amount to fade by; 0 is black, 1 is no fade.
1057 Image::fade (float f)
1059 /* U/V black value for 8-bit colour */
1060 static int const eight_bit_uv = (1 << 7) - 1;
1061 /* U/V black value for 10-bit colour */
1062 static uint16_t const ten_bit_uv = (1 << 9) - 1;
1064 switch (_pixel_format) {
1065 case AV_PIX_FMT_YUV420P:
1068 uint8_t* p = data()[0];
1069 int const lines = sample_size(0).height;
1070 for (int y = 0; y < lines; ++y) {
1072 for (int x = 0; x < line_size()[0]; ++x) {
1073 *q = int(float(*q) * f);
1080 for (int c = 1; c < 3; ++c) {
1081 uint8_t* p = data()[c];
1082 int const lines = sample_size(c).height;
1083 for (int y = 0; y < lines; ++y) {
1085 for (int x = 0; x < line_size()[c]; ++x) {
1086 *q = eight_bit_uv + int((int(*q) - eight_bit_uv) * f);
1096 case AV_PIX_FMT_RGB24:
1099 uint8_t* p = data()[0];
1100 int const lines = sample_size(0).height;
1101 for (int y = 0; y < lines; ++y) {
1103 for (int x = 0; x < line_size()[0]; ++x) {
1104 *q = int (float (*q) * f);
1112 case AV_PIX_FMT_XYZ12LE:
1113 case AV_PIX_FMT_RGB48LE:
1114 /* 16-bit little-endian */
1115 for (int c = 0; c < 3; ++c) {
1116 int const stride_pixels = stride()[c] / 2;
1117 int const line_size_pixels = line_size()[c] / 2;
1118 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1119 int const lines = sample_size(c).height;
1120 for (int y = 0; y < lines; ++y) {
1122 for (int x = 0; x < line_size_pixels; ++x) {
1123 *q = int (float (*q) * f);
1131 case AV_PIX_FMT_YUV422P10LE:
1135 int const stride_pixels = stride()[0] / 2;
1136 int const line_size_pixels = line_size()[0] / 2;
1137 uint16_t* p = reinterpret_cast<uint16_t*> (data()[0]);
1138 int const lines = sample_size(0).height;
1139 for (int y = 0; y < lines; ++y) {
1141 for (int x = 0; x < line_size_pixels; ++x) {
1142 *q = int(float(*q) * f);
1150 for (int c = 1; c < 3; ++c) {
1151 int const stride_pixels = stride()[c] / 2;
1152 int const line_size_pixels = line_size()[c] / 2;
1153 uint16_t* p = reinterpret_cast<uint16_t*> (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_pixels; ++x) {
1158 *q = ten_bit_uv + int((int(*q) - ten_bit_uv) * f);
1169 throw PixelFormatError ("fade()", _pixel_format);
1173 shared_ptr<const Image>
1174 Image::ensure_aligned (shared_ptr<const Image> image)
1176 if (image->aligned()) {
1180 return shared_ptr<Image> (new Image (image, true));
1184 Image::memory_used () const
1187 for (int i = 0; i < planes(); ++i) {
1188 m += _stride[i] * sample_size(i).height;
1211 png_write_data (png_structp png_ptr, png_bytep data, png_size_t length)
1213 Memory* mem = reinterpret_cast<Memory*>(png_get_io_ptr(png_ptr));
1214 size_t size = mem->size + length;
1217 mem->data = reinterpret_cast<uint8_t*>(realloc(mem->data, size));
1219 mem->data = reinterpret_cast<uint8_t*>(malloc(size));
1223 throw EncodeError (N_("could not allocate memory for PNG"));
1226 memcpy (mem->data + mem->size, data, length);
1227 mem->size += length;
1231 png_flush (png_structp)
1237 png_error_fn (png_structp png_ptr, char const * message)
1239 reinterpret_cast<Image*>(png_get_error_ptr(png_ptr))->png_error (message);
1243 Image::png_error (char const * message)
1245 throw EncodeError (String::compose ("Error during PNG write: %1", message));
1249 Image::as_png () const
1251 DCPOMATIC_ASSERT (bytes_per_pixel(0) == 4);
1252 DCPOMATIC_ASSERT (planes() == 1);
1253 if (pixel_format() != AV_PIX_FMT_RGBA) {
1254 return convert_pixel_format(dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_RGBA, true, false)->as_png();
1257 /* error handling? */
1258 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, reinterpret_cast<void*>(const_cast<Image*>(this)), png_error_fn, 0);
1260 throw EncodeError (N_("could not create PNG write struct"));
1265 png_set_write_fn (png_ptr, &state, png_write_data, png_flush);
1267 png_infop info_ptr = png_create_info_struct(png_ptr);
1269 png_destroy_write_struct (&png_ptr, &info_ptr);
1270 throw EncodeError (N_("could not create PNG info struct"));
1273 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);
1275 png_byte ** row_pointers = reinterpret_cast<png_byte **>(png_malloc(png_ptr, size().height * sizeof(png_byte *)));
1276 for (int i = 0; i < size().height; ++i) {
1277 row_pointers[i] = (png_byte *) (data()[0] + i * stride()[0]);
1280 png_write_info (png_ptr, info_ptr);
1281 png_write_image (png_ptr, row_pointers);
1282 png_write_end (png_ptr, info_ptr);
1284 png_destroy_write_struct (&png_ptr, &info_ptr);
1285 png_free (png_ptr, row_pointers);
1287 return dcp::Data (state.data, state.size);