2 Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
4 This file is part of DCP-o-matic.
6 DCP-o-matic is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 DCP-o-matic is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
21 /** @file src/image.cc
22 * @brief A class to describe a video image.
26 #include "exceptions.h"
30 #include "compose.hpp"
31 #include "dcpomatic_socket.h"
32 #include <dcp/rgb_xyz.h>
33 #include <dcp/transfer_function.h>
35 #include <libswscale/swscale.h>
36 #include <libavutil/pixfmt.h>
37 #include <libavutil/pixdesc.h>
38 #include <libavutil/frame.h>
41 #if HAVE_VALGRIND_MEMCHECK_H
42 #include <valgrind/memcheck.h>
54 using std::runtime_error;
55 using boost::shared_ptr;
59 /** The memory alignment, in bytes, used for each row of an image if aligment is requested */
64 Image::vertical_factor (int n) const
70 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
72 throw PixelFormatError ("line_factor()", _pixel_format);
75 return pow (2.0f, d->log2_chroma_h);
79 Image::horizontal_factor (int n) const
85 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
87 throw PixelFormatError ("sample_size()", _pixel_format);
90 return pow (2.0f, d->log2_chroma_w);
93 /** @param n Component index.
94 * @return Number of samples (i.e. pixels, unless sub-sampled) in each direction for this component.
97 Image::sample_size (int n) const
100 lrint (ceil (static_cast<double>(size().width) / horizontal_factor (n))),
101 lrint (ceil (static_cast<double>(size().height) / vertical_factor (n)))
105 /** @return Number of planes */
107 Image::planes () const
109 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
111 throw PixelFormatError ("planes()", _pixel_format);
114 if (_pixel_format == AV_PIX_FMT_PAL8) {
118 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
122 return d->nb_components;
125 /** Crop this image, scale it to `inter_size' and then place it in a black frame of `out_size'.
126 * @param crop Amount to crop by.
127 * @param inter_size Size to scale the cropped image to.
128 * @param out_size Size of output frame; if this is larger than inter_size there will be black padding.
129 * @param yuv_to_rgb YUV to RGB transformation to use, if required.
130 * @param video_range Video range of the image.
131 * @param out_format Output pixel format.
132 * @param out_aligned true to make the output image aligned.
133 * @param out_video_range Video range to use for the output image.
134 * @param fast Try to be fast at the possible expense of quality; at present this means using
135 * fast bilinear rather than bicubic scaling.
138 Image::crop_scale_window (
140 dcp::Size inter_size,
142 dcp::YUVToRGB yuv_to_rgb,
143 VideoRange video_range,
144 AVPixelFormat out_format,
145 VideoRange out_video_range,
150 /* Empirical testing suggests that sws_scale() will crash if
151 the input image is not aligned.
153 DCPOMATIC_ASSERT (aligned ());
155 DCPOMATIC_ASSERT (out_size.width >= inter_size.width);
156 DCPOMATIC_ASSERT (out_size.height >= inter_size.height);
158 shared_ptr<Image> out (new Image(out_format, out_size, out_aligned));
161 /* Size of the image after any crop */
162 dcp::Size const cropped_size = crop.apply (size ());
164 /* Scale context for a scale from cropped_size to inter_size */
165 struct SwsContext* scale_context = sws_getContext (
166 cropped_size.width, cropped_size.height, pixel_format(),
167 inter_size.width, inter_size.height, out_format,
168 fast ? SWS_FAST_BILINEAR : SWS_BICUBIC, 0, 0, 0
171 if (!scale_context) {
172 throw runtime_error (N_("Could not allocate SwsContext"));
175 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
176 int const lut[dcp::YUV_TO_RGB_COUNT] = {
181 /* The 3rd parameter here is:
182 0 -> source range MPEG (i.e. "video", 16-235)
183 1 -> source range JPEG (i.e. "full", 0-255)
185 0 -> destination range MPEG (i.e. "video", 16-235)
186 1 -> destination range JPEG (i.e. "full", 0-255)
188 But remember: sws_setColorspaceDetails ignores these
189 parameters unless the both source and destination images
190 are isYUV or isGray. (If either is not, it uses video range).
192 sws_setColorspaceDetails (
194 sws_getCoefficients (lut[yuv_to_rgb]), video_range == VIDEO_RANGE_VIDEO ? 0 : 1,
195 sws_getCoefficients (lut[yuv_to_rgb]), out_video_range == VIDEO_RANGE_VIDEO ? 0 : 1,
199 AVPixFmtDescriptor const * in_desc = av_pix_fmt_desc_get (_pixel_format);
201 throw PixelFormatError ("crop_scale_window()", _pixel_format);
204 /* Prepare input data pointers with crop */
205 uint8_t* scale_in_data[planes()];
206 for (int c = 0; c < planes(); ++c) {
207 /* To work out the crop in bytes, start by multiplying
208 the crop by the (average) bytes per pixel. Then
209 round down so that we don't crop a subsampled pixel until
210 we've cropped all of its Y-channel pixels.
212 int const x = lrintf (bytes_per_pixel(c) * crop.left) & ~ ((int) in_desc->log2_chroma_w);
213 scale_in_data[c] = data()[c] + x + stride()[c] * (crop.top / vertical_factor(c));
216 /* Corner of the image within out_size */
217 Position<int> const corner ((out_size.width - inter_size.width) / 2, (out_size.height - inter_size.height) / 2);
219 AVPixFmtDescriptor const * out_desc = av_pix_fmt_desc_get (out_format);
221 throw PixelFormatError ("crop_scale_window()", out_format);
224 uint8_t* scale_out_data[out->planes()];
225 for (int c = 0; c < out->planes(); ++c) {
226 /* See the note in the crop loop above */
227 int const x = lrintf (out->bytes_per_pixel(c) * corner.x) & ~ ((int) out_desc->log2_chroma_w);
228 scale_out_data[c] = out->data()[c] + x + out->stride()[c] * (corner.y / out->vertical_factor(c));
233 scale_in_data, stride(),
234 0, cropped_size.height,
235 scale_out_data, out->stride()
238 sws_freeContext (scale_context);
240 if (crop != Crop() && cropped_size == inter_size && _pixel_format == out_format) {
241 /* We are cropping without any scaling or pixel format conversion, so FFmpeg may have left some
242 data behind in our image. Clear it out. It may get to the point where we should just stop
243 trying to be clever with cropping.
245 out->make_part_black (corner.x + cropped_size.width, out_size.width - cropped_size.width);
252 Image::convert_pixel_format (dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
254 return scale(size(), yuv_to_rgb, out_format, out_aligned, fast);
257 /** @param out_size Size to scale to.
258 * @param yuv_to_rgb YUVToRGB transform transform to use, if required.
259 * @param out_format Output pixel format.
260 * @param out_aligned true to make an aligned output image.
261 * @param fast Try to be fast at the possible expense of quality; at present this means using
262 * fast bilinear rather than bicubic scaling.
265 Image::scale (dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
267 /* Empirical testing suggests that sws_scale() will crash if
268 the input image is not aligned.
270 DCPOMATIC_ASSERT (aligned ());
272 shared_ptr<Image> scaled (new Image (out_format, out_size, out_aligned));
274 struct SwsContext* scale_context = sws_getContext (
275 size().width, size().height, pixel_format(),
276 out_size.width, out_size.height, out_format,
277 (fast ? SWS_FAST_BILINEAR : SWS_BICUBIC) | SWS_ACCURATE_RND, 0, 0, 0
280 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
281 int const lut[dcp::YUV_TO_RGB_COUNT] = {
286 /* The 3rd parameter here is:
287 0 -> source range MPEG (i.e. "video", 16-235)
288 1 -> source range JPEG (i.e. "full", 0-255)
290 0 -> destination range MPEG (i.e. "video", 16-235)
291 1 -> destination range JPEG (i.e. "full", 0-255)
293 But remember: sws_setColorspaceDetails ignores these
294 parameters unless the corresponding image isYUV or isGray.
295 (If it's neither, it uses video range).
297 sws_setColorspaceDetails (
299 sws_getCoefficients (lut[yuv_to_rgb]), 0,
300 sws_getCoefficients (lut[yuv_to_rgb]), 0,
308 scaled->data(), scaled->stride()
311 sws_freeContext (scale_context);
316 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
318 Image::yuv_16_black (uint16_t v, bool alpha)
320 memset (data()[0], 0, sample_size(0).height * stride()[0]);
321 for (int i = 1; i < 3; ++i) {
322 int16_t* p = reinterpret_cast<int16_t*> (data()[i]);
323 int const lines = sample_size(i).height;
324 for (int y = 0; y < lines; ++y) {
325 /* We divide by 2 here because we are writing 2 bytes at a time */
326 for (int x = 0; x < line_size()[i] / 2; ++x) {
329 p += stride()[i] / 2;
334 memset (data()[3], 0, sample_size(3).height * stride()[3]);
339 Image::swap_16 (uint16_t v)
341 return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
345 Image::make_part_black (int x, int w)
347 switch (_pixel_format) {
348 case AV_PIX_FMT_RGB24:
349 case AV_PIX_FMT_ARGB:
350 case AV_PIX_FMT_RGBA:
351 case AV_PIX_FMT_ABGR:
352 case AV_PIX_FMT_BGRA:
353 case AV_PIX_FMT_RGB555LE:
354 case AV_PIX_FMT_RGB48LE:
355 case AV_PIX_FMT_RGB48BE:
356 case AV_PIX_FMT_XYZ12LE:
358 int const h = sample_size(0).height;
359 int const bpp = bytes_per_pixel(0);
360 int const s = stride()[0];
361 uint8_t* p = data()[0];
362 for (int y = 0; y < h; y++) {
363 memset (p + x * bpp, 0, w * bpp);
370 throw PixelFormatError ("make_part_black()", _pixel_format);
377 /* U/V black value for 8-bit colour */
378 static uint8_t const eight_bit_uv = (1 << 7) - 1;
379 /* U/V black value for 9-bit colour */
380 static uint16_t const nine_bit_uv = (1 << 8) - 1;
381 /* U/V black value for 10-bit colour */
382 static uint16_t const ten_bit_uv = (1 << 9) - 1;
383 /* U/V black value for 16-bit colour */
384 static uint16_t const sixteen_bit_uv = (1 << 15) - 1;
386 switch (_pixel_format) {
387 case AV_PIX_FMT_YUV420P:
388 case AV_PIX_FMT_YUV422P:
389 case AV_PIX_FMT_YUV444P:
390 case AV_PIX_FMT_YUV411P:
391 memset (data()[0], 0, sample_size(0).height * stride()[0]);
392 memset (data()[1], eight_bit_uv, sample_size(1).height * stride()[1]);
393 memset (data()[2], eight_bit_uv, sample_size(2).height * stride()[2]);
396 case AV_PIX_FMT_YUVJ420P:
397 case AV_PIX_FMT_YUVJ422P:
398 case AV_PIX_FMT_YUVJ444P:
399 memset (data()[0], 0, sample_size(0).height * stride()[0]);
400 memset (data()[1], eight_bit_uv + 1, sample_size(1).height * stride()[1]);
401 memset (data()[2], eight_bit_uv + 1, sample_size(2).height * stride()[2]);
404 case AV_PIX_FMT_YUV422P9LE:
405 case AV_PIX_FMT_YUV444P9LE:
406 yuv_16_black (nine_bit_uv, false);
409 case AV_PIX_FMT_YUV422P9BE:
410 case AV_PIX_FMT_YUV444P9BE:
411 yuv_16_black (swap_16 (nine_bit_uv), false);
414 case AV_PIX_FMT_YUV422P10LE:
415 case AV_PIX_FMT_YUV444P10LE:
416 yuv_16_black (ten_bit_uv, false);
419 case AV_PIX_FMT_YUV422P16LE:
420 case AV_PIX_FMT_YUV444P16LE:
421 yuv_16_black (sixteen_bit_uv, false);
424 case AV_PIX_FMT_YUV444P10BE:
425 case AV_PIX_FMT_YUV422P10BE:
426 yuv_16_black (swap_16 (ten_bit_uv), false);
429 case AV_PIX_FMT_YUVA420P9BE:
430 case AV_PIX_FMT_YUVA422P9BE:
431 case AV_PIX_FMT_YUVA444P9BE:
432 yuv_16_black (swap_16 (nine_bit_uv), true);
435 case AV_PIX_FMT_YUVA420P9LE:
436 case AV_PIX_FMT_YUVA422P9LE:
437 case AV_PIX_FMT_YUVA444P9LE:
438 yuv_16_black (nine_bit_uv, true);
441 case AV_PIX_FMT_YUVA420P10BE:
442 case AV_PIX_FMT_YUVA422P10BE:
443 case AV_PIX_FMT_YUVA444P10BE:
444 yuv_16_black (swap_16 (ten_bit_uv), true);
447 case AV_PIX_FMT_YUVA420P10LE:
448 case AV_PIX_FMT_YUVA422P10LE:
449 case AV_PIX_FMT_YUVA444P10LE:
450 yuv_16_black (ten_bit_uv, true);
453 case AV_PIX_FMT_YUVA420P16BE:
454 case AV_PIX_FMT_YUVA422P16BE:
455 case AV_PIX_FMT_YUVA444P16BE:
456 yuv_16_black (swap_16 (sixteen_bit_uv), true);
459 case AV_PIX_FMT_YUVA420P16LE:
460 case AV_PIX_FMT_YUVA422P16LE:
461 case AV_PIX_FMT_YUVA444P16LE:
462 yuv_16_black (sixteen_bit_uv, true);
465 case AV_PIX_FMT_RGB24:
466 case AV_PIX_FMT_ARGB:
467 case AV_PIX_FMT_RGBA:
468 case AV_PIX_FMT_ABGR:
469 case AV_PIX_FMT_BGRA:
470 case AV_PIX_FMT_RGB555LE:
471 case AV_PIX_FMT_RGB48LE:
472 case AV_PIX_FMT_RGB48BE:
473 case AV_PIX_FMT_XYZ12LE:
474 memset (data()[0], 0, sample_size(0).height * stride()[0]);
477 case AV_PIX_FMT_UYVY422:
479 int const Y = sample_size(0).height;
480 int const X = line_size()[0];
481 uint8_t* p = data()[0];
482 for (int y = 0; y < Y; ++y) {
483 for (int x = 0; x < X / 4; ++x) {
484 *p++ = eight_bit_uv; // Cb
486 *p++ = eight_bit_uv; // Cr
494 throw PixelFormatError ("make_black()", _pixel_format);
499 Image::make_transparent ()
501 if (_pixel_format != AV_PIX_FMT_BGRA && _pixel_format != AV_PIX_FMT_RGBA) {
502 throw PixelFormatError ("make_transparent()", _pixel_format);
505 memset (data()[0], 0, sample_size(0).height * stride()[0]);
509 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
511 /* We're blending RGBA or BGRA images */
512 DCPOMATIC_ASSERT (other->pixel_format() == AV_PIX_FMT_BGRA || other->pixel_format() == AV_PIX_FMT_RGBA);
513 int const blue = other->pixel_format() == AV_PIX_FMT_BGRA ? 0 : 2;
514 int const red = other->pixel_format() == AV_PIX_FMT_BGRA ? 2 : 0;
516 int const other_bpp = 4;
518 int start_tx = position.x;
522 start_ox = -start_tx;
526 int start_ty = position.y;
530 start_oy = -start_ty;
534 switch (_pixel_format) {
535 case AV_PIX_FMT_RGB24:
537 /* Going onto RGB24. First byte is red, second green, third blue */
538 int const this_bpp = 3;
539 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
540 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
541 uint8_t* op = other->data()[0] + oy * other->stride()[0];
542 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
543 float const alpha = float (op[3]) / 255;
544 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
545 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
546 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
554 case AV_PIX_FMT_BGRA:
556 int const this_bpp = 4;
557 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
558 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
559 uint8_t* op = other->data()[0] + oy * other->stride()[0];
560 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
561 float const alpha = float (op[3]) / 255;
562 tp[0] = op[blue] * alpha + tp[0] * (1 - alpha);
563 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
564 tp[2] = op[red] * alpha + tp[2] * (1 - alpha);
565 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
573 case AV_PIX_FMT_RGBA:
575 int const this_bpp = 4;
576 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
577 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
578 uint8_t* op = other->data()[0] + oy * other->stride()[0];
579 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
580 float const alpha = float (op[3]) / 255;
581 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
582 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
583 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
584 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
592 case AV_PIX_FMT_RGB48LE:
594 int const this_bpp = 6;
595 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
596 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
597 uint8_t* op = other->data()[0] + oy * other->stride()[0];
598 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
599 float const alpha = float (op[3]) / 255;
600 /* Blend high bytes */
601 tp[1] = op[red] * alpha + tp[1] * (1 - alpha);
602 tp[3] = op[1] * alpha + tp[3] * (1 - alpha);
603 tp[5] = op[blue] * alpha + tp[5] * (1 - alpha);
611 case AV_PIX_FMT_XYZ12LE:
613 dcp::ColourConversion conv = dcp::ColourConversion::srgb_to_xyz();
614 double fast_matrix[9];
615 dcp::combined_rgb_to_xyz (conv, fast_matrix);
616 double const * lut_in = conv.in()->lut (8, false);
617 double const * lut_out = conv.out()->lut (16, true);
618 int const this_bpp = 6;
619 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
620 uint16_t* tp = reinterpret_cast<uint16_t*> (data()[0] + ty * stride()[0] + start_tx * this_bpp);
621 uint8_t* op = other->data()[0] + oy * other->stride()[0];
622 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
623 float const alpha = float (op[3]) / 255;
625 /* Convert sRGB to XYZ; op is BGRA. First, input gamma LUT */
626 double const r = lut_in[op[red]];
627 double const g = lut_in[op[1]];
628 double const b = lut_in[op[blue]];
630 /* RGB to XYZ, including Bradford transform and DCI companding */
631 double const x = max (0.0, min (65535.0, r * fast_matrix[0] + g * fast_matrix[1] + b * fast_matrix[2]));
632 double const y = max (0.0, min (65535.0, r * fast_matrix[3] + g * fast_matrix[4] + b * fast_matrix[5]));
633 double const z = max (0.0, min (65535.0, r * fast_matrix[6] + g * fast_matrix[7] + b * fast_matrix[8]));
635 /* Out gamma LUT and blend */
636 tp[0] = lrint(lut_out[lrint(x)] * 65535) * alpha + tp[0] * (1 - alpha);
637 tp[1] = lrint(lut_out[lrint(y)] * 65535) * alpha + tp[1] * (1 - alpha);
638 tp[2] = lrint(lut_out[lrint(z)] * 65535) * alpha + tp[2] * (1 - alpha);
646 case AV_PIX_FMT_YUV420P:
648 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
649 dcp::Size const ts = size();
650 dcp::Size const os = yuv->size();
651 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
652 int const hty = ty / 2;
653 int const hoy = oy / 2;
654 uint8_t* tY = data()[0] + (ty * stride()[0]) + start_tx;
655 uint8_t* tU = data()[1] + (hty * stride()[1]) + start_tx / 2;
656 uint8_t* tV = data()[2] + (hty * stride()[2]) + start_tx / 2;
657 uint8_t* oY = yuv->data()[0] + (oy * yuv->stride()[0]) + start_ox;
658 uint8_t* oU = yuv->data()[1] + (hoy * yuv->stride()[1]) + start_ox / 2;
659 uint8_t* oV = yuv->data()[2] + (hoy * yuv->stride()[2]) + start_ox / 2;
660 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
661 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
662 float const a = float(alpha[3]) / 255;
663 *tY = *oY * a + *tY * (1 - a);
664 *tU = *oU * a + *tU * (1 - a);
665 *tV = *oV * a + *tV * (1 - a);
681 case AV_PIX_FMT_YUV420P10:
683 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
684 dcp::Size const ts = size();
685 dcp::Size const os = yuv->size();
686 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
687 int const hty = ty / 2;
688 int const hoy = oy / 2;
689 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
690 uint16_t* tU = ((uint16_t *) (data()[1] + (hty * stride()[1]))) + start_tx / 2;
691 uint16_t* tV = ((uint16_t *) (data()[2] + (hty * stride()[2]))) + start_tx / 2;
692 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
693 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (hoy * yuv->stride()[1]))) + start_ox / 2;
694 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (hoy * yuv->stride()[2]))) + start_ox / 2;
695 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
696 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
697 float const a = float(alpha[3]) / 255;
698 *tY = *oY * a + *tY * (1 - a);
699 *tU = *oU * a + *tU * (1 - a);
700 *tV = *oV * a + *tV * (1 - a);
716 case AV_PIX_FMT_YUV422P10LE:
718 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
719 dcp::Size const ts = size();
720 dcp::Size const os = yuv->size();
721 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
722 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
723 uint16_t* tU = ((uint16_t *) (data()[1] + (ty * stride()[1]))) + start_tx / 2;
724 uint16_t* tV = ((uint16_t *) (data()[2] + (ty * stride()[2]))) + start_tx / 2;
725 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
726 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (oy * yuv->stride()[1]))) + start_ox / 2;
727 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (oy * yuv->stride()[2]))) + start_ox / 2;
728 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
729 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
730 float const a = float(alpha[3]) / 255;
731 *tY = *oY * a + *tY * (1 - a);
732 *tU = *oU * a + *tU * (1 - a);
733 *tV = *oV * a + *tV * (1 - a);
750 throw PixelFormatError ("alpha_blend()", _pixel_format);
755 Image::copy (shared_ptr<const Image> other, Position<int> position)
757 /* Only implemented for RGB24 onto RGB24 so far */
758 DCPOMATIC_ASSERT (_pixel_format == AV_PIX_FMT_RGB24 && other->pixel_format() == AV_PIX_FMT_RGB24);
759 DCPOMATIC_ASSERT (position.x >= 0 && position.y >= 0);
761 int const N = min (position.x + other->size().width, size().width) - position.x;
762 for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
763 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
764 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
765 memcpy (tp, op, N * 3);
770 Image::read_from_socket (shared_ptr<Socket> socket)
772 for (int i = 0; i < planes(); ++i) {
773 uint8_t* p = data()[i];
774 int const lines = sample_size(i).height;
775 for (int y = 0; y < lines; ++y) {
776 socket->read (p, line_size()[i]);
783 Image::write_to_socket (shared_ptr<Socket> socket) const
785 for (int i = 0; i < planes(); ++i) {
786 uint8_t* p = data()[i];
787 int const lines = sample_size(i).height;
788 for (int y = 0; y < lines; ++y) {
789 socket->write (p, line_size()[i]);
796 Image::bytes_per_pixel (int c) const
798 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
800 throw PixelFormatError ("bytes_per_pixel()", _pixel_format);
807 float bpp[4] = { 0, 0, 0, 0 };
809 #ifdef DCPOMATIC_HAVE_AVCOMPONENTDESCRIPTOR_DEPTH_MINUS1
810 bpp[0] = floor ((d->comp[0].depth_minus1 + 8) / 8);
811 if (d->nb_components > 1) {
812 bpp[1] = floor ((d->comp[1].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
814 if (d->nb_components > 2) {
815 bpp[2] = floor ((d->comp[2].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
817 if (d->nb_components > 3) {
818 bpp[3] = floor ((d->comp[3].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
821 bpp[0] = floor ((d->comp[0].depth + 7) / 8);
822 if (d->nb_components > 1) {
823 bpp[1] = floor ((d->comp[1].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
825 if (d->nb_components > 2) {
826 bpp[2] = floor ((d->comp[2].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
828 if (d->nb_components > 3) {
829 bpp[3] = floor ((d->comp[3].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
833 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
834 /* Not planar; sum them up */
835 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
841 /** Construct a Image of a given size and format, allocating memory
844 * @param p Pixel format.
845 * @param s Size in pixels.
846 * @param aligned true to make each row of this image aligned to a ALIGNMENT-byte boundary.
848 Image::Image (AVPixelFormat p, dcp::Size s, bool aligned)
859 _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
860 _data[0] = _data[1] = _data[2] = _data[3] = 0;
862 _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
863 _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
865 _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
866 _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
868 for (int i = 0; i < planes(); ++i) {
869 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
870 _stride[i] = stride_round_up (i, _line_size, _aligned ? ALIGNMENT : 1);
872 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
873 uses a 16-byte fetch to read three bytes (R/G/B) of image data.
874 Hence on the last pixel of the last line it reads over the end of
875 the actual data by 1 byte. If the width of an image is a multiple
876 of the stride alignment there will be no padding at the end of image lines.
877 OS X crashes on this illegal read, though other operating systems don't
878 seem to mind. The nasty + 1 in this malloc makes sure there is always a byte
879 for that instruction to read safely.
881 Further to the above, valgrind is now telling me that ff_rgb24ToY_ssse3
882 over-reads by more then _avx. I can't follow the code to work out how much,
883 so I'll just over-allocate by ALIGNMENT bytes and have done with it. Empirical
884 testing suggests that it works.
886 In addition to these concerns, we may read/write as much as a whole extra line
887 at the end of each plane in cases where we are messing with offsets in order to
888 do pad or crop. To solve this we over-allocate by an extra _stride[i] bytes.
890 As an example: we may write to images starting at an offset so we get some padding.
891 Hence we want to write in the following pattern:
893 block start write start line end
894 |..(padding)..|<------line-size------------->|..(padding)..|
895 |..(padding)..|<------line-size------------->|..(padding)..|
896 |..(padding)..|<------line-size------------->|..(padding)..|
898 where line-size is of the smaller (inter_size) image and the full padded line length is that of
899 out_size. To get things to work we have to tell FFmpeg that the stride is that of out_size.
900 However some parts of FFmpeg (notably rgb48Toxyz12 in swscale.c) process data for the full
901 specified *stride*. This does not matter until we get to the last line:
903 block start write start line end
904 |..(padding)..|<------line-size------------->|XXXwrittenXXX|
905 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXX|
906 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXXXXXwrittenXXX
909 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * (sample_size(i).height + 1) + ALIGNMENT);
910 #if HAVE_VALGRIND_MEMCHECK_H
911 /* The data between the end of the line size and the stride is undefined but processed by
912 libswscale, causing lots of valgrind errors. Mark it all defined to quell these errors.
914 VALGRIND_MAKE_MEM_DEFINED (_data[i], _stride[i] * (sample_size(i).height + 1) + ALIGNMENT);
919 Image::Image (Image const & other)
920 : boost::enable_shared_from_this<Image>(other)
921 , _size (other._size)
922 , _pixel_format (other._pixel_format)
923 , _aligned (other._aligned)
927 for (int i = 0; i < planes(); ++i) {
928 uint8_t* p = _data[i];
929 uint8_t* q = other._data[i];
930 int const lines = sample_size(i).height;
931 for (int j = 0; j < lines; ++j) {
932 memcpy (p, q, _line_size[i]);
934 q += other.stride()[i];
939 Image::Image (AVFrame* frame)
940 : _size (frame->width, frame->height)
941 , _pixel_format (static_cast<AVPixelFormat> (frame->format))
946 for (int i = 0; i < planes(); ++i) {
947 uint8_t* p = _data[i];
948 uint8_t* q = frame->data[i];
949 int const lines = sample_size(i).height;
950 for (int j = 0; j < lines; ++j) {
951 memcpy (p, q, _line_size[i]);
953 /* AVFrame's linesize is what we call `stride' */
954 q += frame->linesize[i];
959 Image::Image (shared_ptr<const Image> other, bool aligned)
960 : _size (other->_size)
961 , _pixel_format (other->_pixel_format)
966 for (int i = 0; i < planes(); ++i) {
967 DCPOMATIC_ASSERT (line_size()[i] == other->line_size()[i]);
968 uint8_t* p = _data[i];
969 uint8_t* q = other->data()[i];
970 int const lines = sample_size(i).height;
971 for (int j = 0; j < lines; ++j) {
972 memcpy (p, q, line_size()[i]);
974 q += other->stride()[i];
980 Image::operator= (Image const & other)
982 if (this == &other) {
992 Image::swap (Image & other)
994 std::swap (_size, other._size);
995 std::swap (_pixel_format, other._pixel_format);
997 for (int i = 0; i < 4; ++i) {
998 std::swap (_data[i], other._data[i]);
999 std::swap (_line_size[i], other._line_size[i]);
1000 std::swap (_stride[i], other._stride[i]);
1003 std::swap (_aligned, other._aligned);
1008 for (int i = 0; i < planes(); ++i) {
1013 av_free (_line_size);
1018 Image::data () const
1024 Image::line_size () const
1030 Image::stride () const
1036 Image::size () const
1042 Image::aligned () const
1048 merge (list<PositionImage> images)
1050 if (images.empty ()) {
1051 return PositionImage ();
1054 if (images.size() == 1) {
1055 return images.front ();
1058 dcpomatic::Rect<int> all (images.front().position, images.front().image->size().width, images.front().image->size().height);
1059 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1060 all.extend (dcpomatic::Rect<int> (i->position, i->image->size().width, i->image->size().height));
1063 shared_ptr<Image> merged (new Image (images.front().image->pixel_format (), dcp::Size (all.width, all.height), true));
1064 merged->make_transparent ();
1065 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1066 merged->alpha_blend (i->image, i->position - all.position());
1069 return PositionImage (merged, all.position ());
1073 operator== (Image const & a, Image const & b)
1075 if (a.planes() != b.planes() || a.pixel_format() != b.pixel_format() || a.aligned() != b.aligned()) {
1079 for (int c = 0; c < a.planes(); ++c) {
1080 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]) {
1084 uint8_t* p = a.data()[c];
1085 uint8_t* q = b.data()[c];
1086 int const lines = a.sample_size(c).height;
1087 for (int y = 0; y < lines; ++y) {
1088 if (memcmp (p, q, a.line_size()[c]) != 0) {
1101 * @param f Amount to fade by; 0 is black, 1 is no fade.
1104 Image::fade (float f)
1106 /* U/V black value for 8-bit colour */
1107 static int const eight_bit_uv = (1 << 7) - 1;
1108 /* U/V black value for 10-bit colour */
1109 static uint16_t const ten_bit_uv = (1 << 9) - 1;
1111 switch (_pixel_format) {
1112 case AV_PIX_FMT_YUV420P:
1115 uint8_t* p = data()[0];
1116 int const lines = sample_size(0).height;
1117 for (int y = 0; y < lines; ++y) {
1119 for (int x = 0; x < line_size()[0]; ++x) {
1120 *q = int(float(*q) * f);
1127 for (int c = 1; c < 3; ++c) {
1128 uint8_t* p = data()[c];
1129 int const lines = sample_size(c).height;
1130 for (int y = 0; y < lines; ++y) {
1132 for (int x = 0; x < line_size()[c]; ++x) {
1133 *q = eight_bit_uv + int((int(*q) - eight_bit_uv) * f);
1143 case AV_PIX_FMT_RGB24:
1146 uint8_t* p = data()[0];
1147 int const lines = sample_size(0).height;
1148 for (int y = 0; y < lines; ++y) {
1150 for (int x = 0; x < line_size()[0]; ++x) {
1151 *q = int (float (*q) * f);
1159 case AV_PIX_FMT_XYZ12LE:
1160 case AV_PIX_FMT_RGB48LE:
1161 /* 16-bit little-endian */
1162 for (int c = 0; c < 3; ++c) {
1163 int const stride_pixels = stride()[c] / 2;
1164 int const line_size_pixels = line_size()[c] / 2;
1165 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1166 int const lines = sample_size(c).height;
1167 for (int y = 0; y < lines; ++y) {
1169 for (int x = 0; x < line_size_pixels; ++x) {
1170 *q = int (float (*q) * f);
1178 case AV_PIX_FMT_YUV422P10LE:
1182 int const stride_pixels = stride()[0] / 2;
1183 int const line_size_pixels = line_size()[0] / 2;
1184 uint16_t* p = reinterpret_cast<uint16_t*> (data()[0]);
1185 int const lines = sample_size(0).height;
1186 for (int y = 0; y < lines; ++y) {
1188 for (int x = 0; x < line_size_pixels; ++x) {
1189 *q = int(float(*q) * f);
1197 for (int c = 1; c < 3; ++c) {
1198 int const stride_pixels = stride()[c] / 2;
1199 int const line_size_pixels = line_size()[c] / 2;
1200 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1201 int const lines = sample_size(c).height;
1202 for (int y = 0; y < lines; ++y) {
1204 for (int x = 0; x < line_size_pixels; ++x) {
1205 *q = ten_bit_uv + int((int(*q) - ten_bit_uv) * f);
1216 throw PixelFormatError ("fade()", _pixel_format);
1220 shared_ptr<const Image>
1221 Image::ensure_aligned (shared_ptr<const Image> image)
1223 if (image->aligned()) {
1227 return shared_ptr<Image> (new Image (image, true));
1231 Image::memory_used () const
1234 for (int i = 0; i < planes(); ++i) {
1235 m += _stride[i] * sample_size(i).height;
1258 png_write_data (png_structp png_ptr, png_bytep data, png_size_t length)
1260 Memory* mem = reinterpret_cast<Memory*>(png_get_io_ptr(png_ptr));
1261 size_t size = mem->size + length;
1264 mem->data = reinterpret_cast<uint8_t*>(realloc(mem->data, size));
1266 mem->data = reinterpret_cast<uint8_t*>(malloc(size));
1270 throw EncodeError (N_("could not allocate memory for PNG"));
1273 memcpy (mem->data + mem->size, data, length);
1274 mem->size += length;
1278 png_flush (png_structp)
1284 png_error_fn (png_structp png_ptr, char const * message)
1286 reinterpret_cast<Image*>(png_get_error_ptr(png_ptr))->png_error (message);
1290 Image::png_error (char const * message)
1292 throw EncodeError (String::compose ("Error during PNG write: %1", message));
1296 Image::as_png () const
1298 DCPOMATIC_ASSERT (bytes_per_pixel(0) == 4);
1299 DCPOMATIC_ASSERT (planes() == 1);
1300 if (pixel_format() != AV_PIX_FMT_RGBA) {
1301 return convert_pixel_format(dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_RGBA, true, false)->as_png();
1304 /* error handling? */
1305 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, reinterpret_cast<void*>(const_cast<Image*>(this)), png_error_fn, 0);
1307 throw EncodeError (N_("could not create PNG write struct"));
1312 png_set_write_fn (png_ptr, &state, png_write_data, png_flush);
1314 png_infop info_ptr = png_create_info_struct(png_ptr);
1316 png_destroy_write_struct (&png_ptr, &info_ptr);
1317 throw EncodeError (N_("could not create PNG info struct"));
1320 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);
1322 png_byte ** row_pointers = reinterpret_cast<png_byte **>(png_malloc(png_ptr, size().height * sizeof(png_byte *)));
1323 for (int i = 0; i < size().height; ++i) {
1324 row_pointers[i] = (png_byte *) (data()[0] + i * stride()[0]);
1327 png_write_info (png_ptr, info_ptr);
1328 png_write_image (png_ptr, row_pointers);
1329 png_write_end (png_ptr, info_ptr);
1331 png_destroy_write_struct (&png_ptr, &info_ptr);
1332 png_free (png_ptr, row_pointers);
1334 return dcp::ArrayData (state.data, state.size);
1339 Image::video_range_to_full_range ()
1341 switch (_pixel_format) {
1342 case AV_PIX_FMT_RGB24:
1344 float const factor = 256.0 / 219.0;
1345 uint8_t* p = data()[0];
1346 int const lines = sample_size(0).height;
1347 for (int y = 0; y < lines; ++y) {
1349 for (int x = 0; x < line_size()[0]; ++x) {
1350 *q = int((*q - 16) * factor);
1357 case AV_PIX_FMT_GBRP12LE:
1359 float const factor = 4096.0 / 3504.0;
1360 for (int c = 0; c < 3; ++c) {
1361 uint16_t* p = reinterpret_cast<uint16_t*>(data()[c]);
1362 int const lines = sample_size(c).height;
1363 for (int y = 0; y < lines; ++y) {
1365 int const line_size_pixels = line_size()[c] / 2;
1366 for (int x = 0; x < line_size_pixels; ++x) {
1367 *q = int((*q - 256) * factor);
1375 throw PixelFormatError ("video_range_to_full_range()", _pixel_format);