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 ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
113 return d->nb_components;
116 /** Crop this image, scale it to `inter_size' and then place it in a black frame of `out_size'.
117 * @param crop Amount to crop by.
118 * @param inter_size Size to scale the cropped image to.
119 * @param out_size Size of output frame; if this is larger than inter_size there will be black padding.
120 * @param yuv_to_rgb YUV to RGB transformation to use, if required.
121 * @param out_format Output pixel format.
122 * @param out_aligned true to make the output image aligned.
123 * @param fast Try to be fast at the possible expense of quality; at present this means using
124 * fast bilinear rather than bicubic scaling.
127 Image::crop_scale_window (
128 Crop crop, dcp::Size inter_size, dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast
131 /* Empirical testing suggests that sws_scale() will crash if
132 the input image is not aligned.
134 DCPOMATIC_ASSERT (aligned ());
136 DCPOMATIC_ASSERT (out_size.width >= inter_size.width);
137 DCPOMATIC_ASSERT (out_size.height >= inter_size.height);
139 /* Here's an image of out_size. Below we may write to it starting at an offset so we get some padding.
140 Hence we want to write in the following pattern:
142 block start write start line end
143 |..(padding)..|<------line-size------------->|..(padding)..|
144 |..(padding)..|<------line-size------------->|..(padding)..|
145 |..(padding)..|<------line-size------------->|..(padding)..|
147 where line-size is of the smaller (inter_size) image and the full padded line length is that of
148 out_size. To get things to work we have to tell FFmpeg that the stride is that of out_size.
149 However some parts of FFmpeg (notably rgb48Toxyz12 in swscale.c) process data for the full
150 specified *stride*. This does not matter until we get to the last line:
152 block start write start line end
153 |..(padding)..|<------line-size------------->|XXXwrittenXXX|
154 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXX|
155 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXXXXXwrittenXXX
158 To get around this, we ask Image to overallocate its buffers by the overrun.
161 shared_ptr<Image> out (new Image (out_format, out_size, out_aligned, (out_size.width - inter_size.width) / 2));
164 /* Size of the image after any crop */
165 dcp::Size const cropped_size = crop.apply (size ());
167 /* Scale context for a scale from cropped_size to inter_size */
168 struct SwsContext* scale_context = sws_getContext (
169 cropped_size.width, cropped_size.height, pixel_format(),
170 inter_size.width, inter_size.height, out_format,
171 fast ? SWS_FAST_BILINEAR : SWS_BICUBIC, 0, 0, 0
174 if (!scale_context) {
175 throw runtime_error (N_("Could not allocate SwsContext"));
178 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
179 int const lut[dcp::YUV_TO_RGB_COUNT] = {
184 sws_setColorspaceDetails (
186 sws_getCoefficients (lut[yuv_to_rgb]), 0,
187 sws_getCoefficients (lut[yuv_to_rgb]), 0,
191 AVPixFmtDescriptor const * in_desc = av_pix_fmt_desc_get (_pixel_format);
193 throw PixelFormatError ("crop_scale_window()", _pixel_format);
196 /* Prepare input data pointers with crop */
197 uint8_t* scale_in_data[planes()];
198 for (int c = 0; c < planes(); ++c) {
199 /* To work out the crop in bytes, start by multiplying
200 the crop by the (average) bytes per pixel. Then
201 round down so that we don't crop a subsampled pixel until
202 we've cropped all of its Y-channel pixels.
204 int const x = lrintf (bytes_per_pixel(c) * crop.left) & ~ ((int) in_desc->log2_chroma_w);
205 scale_in_data[c] = data()[c] + x + stride()[c] * (crop.top / vertical_factor(c));
208 /* Corner of the image within out_size */
209 Position<int> const corner ((out_size.width - inter_size.width) / 2, (out_size.height - inter_size.height) / 2);
211 AVPixFmtDescriptor const * out_desc = av_pix_fmt_desc_get (out_format);
213 throw PixelFormatError ("crop_scale_window()", out_format);
216 uint8_t* scale_out_data[out->planes()];
217 for (int c = 0; c < out->planes(); ++c) {
218 /* See the note in the crop loop above */
219 int const x = lrintf (out->bytes_per_pixel(c) * corner.x) & ~ ((int) out_desc->log2_chroma_w);
220 scale_out_data[c] = out->data()[c] + x + out->stride()[c] * (corner.y / out->vertical_factor(c));
225 scale_in_data, stride(),
226 0, cropped_size.height,
227 scale_out_data, out->stride()
230 sws_freeContext (scale_context);
236 Image::convert_pixel_format (dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
238 return scale(size(), yuv_to_rgb, out_format, out_aligned, fast);
241 /** @param out_size Size to scale to.
242 * @param yuv_to_rgb YUVToRGB transform transform to use, if required.
243 * @param out_format Output pixel format.
244 * @param out_aligned true to make an aligned output image.
245 * @param fast Try to be fast at the possible expense of quality; at present this means using
246 * fast bilinear rather than bicubic scaling.
249 Image::scale (dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
251 /* Empirical testing suggests that sws_scale() will crash if
252 the input image is not aligned.
254 DCPOMATIC_ASSERT (aligned ());
256 shared_ptr<Image> scaled (new Image (out_format, out_size, out_aligned));
258 struct SwsContext* scale_context = sws_getContext (
259 size().width, size().height, pixel_format(),
260 out_size.width, out_size.height, out_format,
261 (fast ? SWS_FAST_BILINEAR : SWS_BICUBIC) | SWS_ACCURATE_RND, 0, 0, 0
264 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
265 int const lut[dcp::YUV_TO_RGB_COUNT] = {
270 sws_setColorspaceDetails (
272 sws_getCoefficients (lut[yuv_to_rgb]), 0,
273 sws_getCoefficients (lut[yuv_to_rgb]), 0,
281 scaled->data(), scaled->stride()
284 sws_freeContext (scale_context);
289 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
291 Image::yuv_16_black (uint16_t v, bool alpha)
293 memset (data()[0], 0, sample_size(0).height * stride()[0]);
294 for (int i = 1; i < 3; ++i) {
295 int16_t* p = reinterpret_cast<int16_t*> (data()[i]);
296 int const lines = sample_size(i).height;
297 for (int y = 0; y < lines; ++y) {
298 /* We divide by 2 here because we are writing 2 bytes at a time */
299 for (int x = 0; x < line_size()[i] / 2; ++x) {
302 p += stride()[i] / 2;
307 memset (data()[3], 0, sample_size(3).height * stride()[3]);
312 Image::swap_16 (uint16_t v)
314 return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
320 /* U/V black value for 8-bit colour */
321 static uint8_t const eight_bit_uv = (1 << 7) - 1;
322 /* U/V black value for 9-bit colour */
323 static uint16_t const nine_bit_uv = (1 << 8) - 1;
324 /* U/V black value for 10-bit colour */
325 static uint16_t const ten_bit_uv = (1 << 9) - 1;
326 /* U/V black value for 16-bit colour */
327 static uint16_t const sixteen_bit_uv = (1 << 15) - 1;
329 switch (_pixel_format) {
330 case AV_PIX_FMT_YUV420P:
331 case AV_PIX_FMT_YUV422P:
332 case AV_PIX_FMT_YUV444P:
333 case AV_PIX_FMT_YUV411P:
334 memset (data()[0], 0, sample_size(0).height * stride()[0]);
335 memset (data()[1], eight_bit_uv, sample_size(1).height * stride()[1]);
336 memset (data()[2], eight_bit_uv, sample_size(2).height * stride()[2]);
339 case AV_PIX_FMT_YUVJ420P:
340 case AV_PIX_FMT_YUVJ422P:
341 case AV_PIX_FMT_YUVJ444P:
342 memset (data()[0], 0, sample_size(0).height * stride()[0]);
343 memset (data()[1], eight_bit_uv + 1, sample_size(1).height * stride()[1]);
344 memset (data()[2], eight_bit_uv + 1, sample_size(2).height * stride()[2]);
347 case AV_PIX_FMT_YUV422P9LE:
348 case AV_PIX_FMT_YUV444P9LE:
349 yuv_16_black (nine_bit_uv, false);
352 case AV_PIX_FMT_YUV422P9BE:
353 case AV_PIX_FMT_YUV444P9BE:
354 yuv_16_black (swap_16 (nine_bit_uv), false);
357 case AV_PIX_FMT_YUV422P10LE:
358 case AV_PIX_FMT_YUV444P10LE:
359 yuv_16_black (ten_bit_uv, false);
362 case AV_PIX_FMT_YUV422P16LE:
363 case AV_PIX_FMT_YUV444P16LE:
364 yuv_16_black (sixteen_bit_uv, false);
367 case AV_PIX_FMT_YUV444P10BE:
368 case AV_PIX_FMT_YUV422P10BE:
369 yuv_16_black (swap_16 (ten_bit_uv), false);
372 case AV_PIX_FMT_YUVA420P9BE:
373 case AV_PIX_FMT_YUVA422P9BE:
374 case AV_PIX_FMT_YUVA444P9BE:
375 yuv_16_black (swap_16 (nine_bit_uv), true);
378 case AV_PIX_FMT_YUVA420P9LE:
379 case AV_PIX_FMT_YUVA422P9LE:
380 case AV_PIX_FMT_YUVA444P9LE:
381 yuv_16_black (nine_bit_uv, true);
384 case AV_PIX_FMT_YUVA420P10BE:
385 case AV_PIX_FMT_YUVA422P10BE:
386 case AV_PIX_FMT_YUVA444P10BE:
387 yuv_16_black (swap_16 (ten_bit_uv), true);
390 case AV_PIX_FMT_YUVA420P10LE:
391 case AV_PIX_FMT_YUVA422P10LE:
392 case AV_PIX_FMT_YUVA444P10LE:
393 yuv_16_black (ten_bit_uv, true);
396 case AV_PIX_FMT_YUVA420P16BE:
397 case AV_PIX_FMT_YUVA422P16BE:
398 case AV_PIX_FMT_YUVA444P16BE:
399 yuv_16_black (swap_16 (sixteen_bit_uv), true);
402 case AV_PIX_FMT_YUVA420P16LE:
403 case AV_PIX_FMT_YUVA422P16LE:
404 case AV_PIX_FMT_YUVA444P16LE:
405 yuv_16_black (sixteen_bit_uv, true);
408 case AV_PIX_FMT_RGB24:
409 case AV_PIX_FMT_ARGB:
410 case AV_PIX_FMT_RGBA:
411 case AV_PIX_FMT_ABGR:
412 case AV_PIX_FMT_BGRA:
413 case AV_PIX_FMT_RGB555LE:
414 case AV_PIX_FMT_RGB48LE:
415 case AV_PIX_FMT_RGB48BE:
416 case AV_PIX_FMT_XYZ12LE:
417 memset (data()[0], 0, sample_size(0).height * stride()[0]);
420 case AV_PIX_FMT_UYVY422:
422 int const Y = sample_size(0).height;
423 int const X = line_size()[0];
424 uint8_t* p = data()[0];
425 for (int y = 0; y < Y; ++y) {
426 for (int x = 0; x < X / 4; ++x) {
427 *p++ = eight_bit_uv; // Cb
429 *p++ = eight_bit_uv; // Cr
437 throw PixelFormatError ("make_black()", _pixel_format);
442 Image::make_transparent ()
444 if (_pixel_format != AV_PIX_FMT_BGRA) {
445 throw PixelFormatError ("make_transparent()", _pixel_format);
448 memset (data()[0], 0, sample_size(0).height * stride()[0]);
452 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
454 /* We're blending BGRA images; first byte is blue, second byte is green, third byte red, fourth byte alpha */
455 DCPOMATIC_ASSERT (other->pixel_format() == AV_PIX_FMT_BGRA);
456 int const other_bpp = 4;
458 int start_tx = position.x;
462 start_ox = -start_tx;
466 int start_ty = position.y;
470 start_oy = -start_ty;
474 switch (_pixel_format) {
475 case AV_PIX_FMT_RGB24:
477 /* Going onto RGB24. First byte is red, second green, third blue */
478 int const this_bpp = 3;
479 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
480 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
481 uint8_t* op = other->data()[0] + oy * other->stride()[0];
482 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
483 float const alpha = float (op[3]) / 255;
484 tp[0] = op[2] * alpha + tp[0] * (1 - alpha);
485 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
486 tp[2] = op[0] * alpha + tp[2] * (1 - alpha);
494 case AV_PIX_FMT_BGRA:
496 int const this_bpp = 4;
497 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
498 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
499 uint8_t* op = other->data()[0] + oy * other->stride()[0];
500 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
501 float const alpha = float (op[3]) / 255;
502 tp[0] = op[0] * alpha + tp[0] * (1 - alpha);
503 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
504 tp[2] = op[2] * alpha + tp[2] * (1 - alpha);
505 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
513 case AV_PIX_FMT_RGBA:
515 int const this_bpp = 4;
516 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
517 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
518 uint8_t* op = other->data()[0] + oy * other->stride()[0];
519 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
520 float const alpha = float (op[3]) / 255;
521 tp[0] = op[2] * alpha + tp[0] * (1 - alpha);
522 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
523 tp[2] = op[0] * alpha + tp[2] * (1 - alpha);
524 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
532 case AV_PIX_FMT_RGB48LE:
534 int const this_bpp = 6;
535 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
536 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
537 uint8_t* op = other->data()[0] + oy * other->stride()[0];
538 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
539 float const alpha = float (op[3]) / 255;
540 /* Blend high bytes */
541 tp[1] = op[2] * alpha + tp[1] * (1 - alpha);
542 tp[3] = op[1] * alpha + tp[3] * (1 - alpha);
543 tp[5] = op[0] * alpha + tp[5] * (1 - alpha);
551 case AV_PIX_FMT_XYZ12LE:
553 dcp::ColourConversion conv = dcp::ColourConversion::srgb_to_xyz();
554 double fast_matrix[9];
555 dcp::combined_rgb_to_xyz (conv, fast_matrix);
556 double const * lut_in = conv.in()->lut (8, false);
557 double const * lut_out = conv.out()->lut (16, true);
558 int const this_bpp = 6;
559 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
560 uint16_t* tp = reinterpret_cast<uint16_t*> (data()[0] + ty * stride()[0] + start_tx * this_bpp);
561 uint8_t* op = other->data()[0] + oy * other->stride()[0];
562 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
563 float const alpha = float (op[3]) / 255;
565 /* Convert sRGB to XYZ; op is BGRA. First, input gamma LUT */
566 double const r = lut_in[op[2]];
567 double const g = lut_in[op[1]];
568 double const b = lut_in[op[0]];
570 /* RGB to XYZ, including Bradford transform and DCI companding */
571 double const x = max (0.0, min (65535.0, r * fast_matrix[0] + g * fast_matrix[1] + b * fast_matrix[2]));
572 double const y = max (0.0, min (65535.0, r * fast_matrix[3] + g * fast_matrix[4] + b * fast_matrix[5]));
573 double const z = max (0.0, min (65535.0, r * fast_matrix[6] + g * fast_matrix[7] + b * fast_matrix[8]));
575 /* Out gamma LUT and blend */
576 tp[0] = lrint(lut_out[lrint(x)] * 65535) * alpha + tp[0] * (1 - alpha);
577 tp[1] = lrint(lut_out[lrint(y)] * 65535) * alpha + tp[1] * (1 - alpha);
578 tp[2] = lrint(lut_out[lrint(z)] * 65535) * alpha + tp[2] * (1 - alpha);
586 case AV_PIX_FMT_YUV420P:
588 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
589 dcp::Size const ts = size();
590 dcp::Size const os = yuv->size();
591 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
592 int const hty = ty / 2;
593 int const hoy = oy / 2;
594 uint8_t* tY = data()[0] + (ty * stride()[0]) + start_tx;
595 uint8_t* tU = data()[1] + (hty * stride()[1]) + start_tx / 2;
596 uint8_t* tV = data()[2] + (hty * stride()[2]) + start_tx / 2;
597 uint8_t* oY = yuv->data()[0] + (oy * yuv->stride()[0]) + start_ox;
598 uint8_t* oU = yuv->data()[1] + (hoy * yuv->stride()[1]) + start_ox / 2;
599 uint8_t* oV = yuv->data()[2] + (hoy * yuv->stride()[2]) + start_ox / 2;
600 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
601 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
602 float const a = float(alpha[3]) / 255;
603 *tY = *oY * a + *tY * (1 - a);
604 *tU = *oU * a + *tU * (1 - a);
605 *tV = *oV * a + *tV * (1 - a);
621 case AV_PIX_FMT_YUV420P10:
623 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
624 dcp::Size const ts = size();
625 dcp::Size const os = yuv->size();
626 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
627 int const hty = ty / 2;
628 int const hoy = oy / 2;
629 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
630 uint16_t* tU = ((uint16_t *) (data()[1] + (hty * stride()[1]))) + start_tx / 2;
631 uint16_t* tV = ((uint16_t *) (data()[2] + (hty * stride()[2]))) + start_tx / 2;
632 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
633 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (hoy * yuv->stride()[1]))) + start_ox / 2;
634 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (hoy * yuv->stride()[2]))) + start_ox / 2;
635 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
636 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
637 float const a = float(alpha[3]) / 255;
638 *tY = *oY * a + *tY * (1 - a);
639 *tU = *oU * a + *tU * (1 - a);
640 *tV = *oV * a + *tV * (1 - a);
656 case AV_PIX_FMT_YUV422P10LE:
658 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
659 dcp::Size const ts = size();
660 dcp::Size const os = yuv->size();
661 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
662 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
663 uint16_t* tU = ((uint16_t *) (data()[1] + (ty * stride()[1]))) + start_tx / 2;
664 uint16_t* tV = ((uint16_t *) (data()[2] + (ty * stride()[2]))) + start_tx / 2;
665 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
666 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (oy * yuv->stride()[1]))) + start_ox / 2;
667 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (oy * yuv->stride()[2]))) + start_ox / 2;
668 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
669 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
670 float const a = float(alpha[3]) / 255;
671 *tY = *oY * a + *tY * (1 - a);
672 *tU = *oU * a + *tU * (1 - a);
673 *tV = *oV * a + *tV * (1 - a);
690 throw PixelFormatError ("alpha_blend()", _pixel_format);
695 Image::copy (shared_ptr<const Image> other, Position<int> position)
697 /* Only implemented for RGB24 onto RGB24 so far */
698 DCPOMATIC_ASSERT (_pixel_format == AV_PIX_FMT_RGB24 && other->pixel_format() == AV_PIX_FMT_RGB24);
699 DCPOMATIC_ASSERT (position.x >= 0 && position.y >= 0);
701 int const N = min (position.x + other->size().width, size().width) - position.x;
702 for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
703 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
704 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
705 memcpy (tp, op, N * 3);
710 Image::read_from_socket (shared_ptr<Socket> socket)
712 for (int i = 0; i < planes(); ++i) {
713 uint8_t* p = data()[i];
714 int const lines = sample_size(i).height;
715 for (int y = 0; y < lines; ++y) {
716 socket->read (p, line_size()[i]);
723 Image::write_to_socket (shared_ptr<Socket> socket) const
725 for (int i = 0; i < planes(); ++i) {
726 uint8_t* p = data()[i];
727 int const lines = sample_size(i).height;
728 for (int y = 0; y < lines; ++y) {
729 socket->write (p, line_size()[i]);
736 Image::bytes_per_pixel (int c) const
738 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
740 throw PixelFormatError ("bytes_per_pixel()", _pixel_format);
747 float bpp[4] = { 0, 0, 0, 0 };
749 #ifdef DCPOMATIC_HAVE_AVCOMPONENTDESCRIPTOR_DEPTH_MINUS1
750 bpp[0] = floor ((d->comp[0].depth_minus1 + 8) / 8);
751 if (d->nb_components > 1) {
752 bpp[1] = floor ((d->comp[1].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
754 if (d->nb_components > 2) {
755 bpp[2] = floor ((d->comp[2].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
757 if (d->nb_components > 3) {
758 bpp[3] = floor ((d->comp[3].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
761 bpp[0] = floor ((d->comp[0].depth + 7) / 8);
762 if (d->nb_components > 1) {
763 bpp[1] = floor ((d->comp[1].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
765 if (d->nb_components > 2) {
766 bpp[2] = floor ((d->comp[2].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
768 if (d->nb_components > 3) {
769 bpp[3] = floor ((d->comp[3].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
773 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
774 /* Not planar; sum them up */
775 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
781 /** Construct a Image of a given size and format, allocating memory
784 * @param p Pixel format.
785 * @param s Size in pixels.
786 * @param aligned true to make each row of this image aligned to a 32-byte boundary.
787 * @param extra_pixels Amount of extra "run-off" memory to allocate at the end of each plane in pixels.
789 Image::Image (AVPixelFormat p, dcp::Size s, bool aligned, int extra_pixels)
793 , _extra_pixels (extra_pixels)
801 _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
802 _data[0] = _data[1] = _data[2] = _data[3] = 0;
804 _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
805 _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
807 _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
808 _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
810 for (int i = 0; i < planes(); ++i) {
811 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
812 _stride[i] = stride_round_up (i, _line_size, _aligned ? 32 : 1);
814 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
815 uses a 16-byte fetch to read three bytes (R/G/B) of image data.
816 Hence on the last pixel of the last line it reads over the end of
817 the actual data by 1 byte. If the width of an image is a multiple
818 of the stride alignment there will be no padding at the end of image lines.
819 OS X crashes on this illegal read, though other operating systems don't
820 seem to mind. The nasty + 1 in this malloc makes sure there is always a byte
821 for that instruction to read safely.
823 Further to the above, valgrind is now telling me that ff_rgb24ToY_ssse3
824 over-reads by more then _avx. I can't follow the code to work out how much,
825 so I'll just over-allocate by 32 bytes and have done with it. Empirical
826 testing suggests that it works.
828 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * sample_size(i).height + _extra_pixels * bytes_per_pixel(i) + 32);
829 #if HAVE_VALGRIND_MEMCHECK_H
830 /* The data between the end of the line size and the stride is undefined but processed by
831 libswscale, causing lots of valgrind errors. Mark it all defined to quell these errors.
833 VALGRIND_MAKE_MEM_DEFINED (_data[i], _stride[i] * sample_size(i).height + _extra_pixels * bytes_per_pixel(i) + 32);
838 Image::Image (Image const & other)
839 : boost::enable_shared_from_this<Image>(other)
840 , _size (other._size)
841 , _pixel_format (other._pixel_format)
842 , _aligned (other._aligned)
843 , _extra_pixels (other._extra_pixels)
847 for (int i = 0; i < planes(); ++i) {
848 uint8_t* p = _data[i];
849 uint8_t* q = other._data[i];
850 int const lines = sample_size(i).height;
851 for (int j = 0; j < lines; ++j) {
852 memcpy (p, q, _line_size[i]);
854 q += other.stride()[i];
859 Image::Image (AVFrame* frame)
860 : _size (frame->width, frame->height)
861 , _pixel_format (static_cast<AVPixelFormat> (frame->format))
867 for (int i = 0; i < planes(); ++i) {
868 uint8_t* p = _data[i];
869 uint8_t* q = frame->data[i];
870 int const lines = sample_size(i).height;
871 for (int j = 0; j < lines; ++j) {
872 memcpy (p, q, _line_size[i]);
874 /* AVFrame's linesize is what we call `stride' */
875 q += frame->linesize[i];
880 Image::Image (shared_ptr<const Image> other, bool aligned)
881 : _size (other->_size)
882 , _pixel_format (other->_pixel_format)
884 , _extra_pixels (other->_extra_pixels)
888 for (int i = 0; i < planes(); ++i) {
889 DCPOMATIC_ASSERT (line_size()[i] == other->line_size()[i]);
890 uint8_t* p = _data[i];
891 uint8_t* q = other->data()[i];
892 int const lines = sample_size(i).height;
893 for (int j = 0; j < lines; ++j) {
894 memcpy (p, q, line_size()[i]);
896 q += other->stride()[i];
902 Image::operator= (Image const & other)
904 if (this == &other) {
914 Image::swap (Image & other)
916 std::swap (_size, other._size);
917 std::swap (_pixel_format, other._pixel_format);
919 for (int i = 0; i < 4; ++i) {
920 std::swap (_data[i], other._data[i]);
921 std::swap (_line_size[i], other._line_size[i]);
922 std::swap (_stride[i], other._stride[i]);
925 std::swap (_aligned, other._aligned);
926 std::swap (_extra_pixels, other._extra_pixels);
929 /** Destroy a Image */
932 for (int i = 0; i < planes(); ++i) {
937 av_free (_line_size);
948 Image::line_size () const
954 Image::stride () const
966 Image::aligned () const
972 merge (list<PositionImage> images)
974 if (images.empty ()) {
975 return PositionImage ();
978 if (images.size() == 1) {
979 return images.front ();
982 dcpomatic::Rect<int> all (images.front().position, images.front().image->size().width, images.front().image->size().height);
983 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
984 all.extend (dcpomatic::Rect<int> (i->position, i->image->size().width, i->image->size().height));
987 shared_ptr<Image> merged (new Image (images.front().image->pixel_format (), dcp::Size (all.width, all.height), true));
988 merged->make_transparent ();
989 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
990 merged->alpha_blend (i->image, i->position - all.position());
993 return PositionImage (merged, all.position ());
997 operator== (Image const & a, Image const & b)
999 if (a.planes() != b.planes() || a.pixel_format() != b.pixel_format() || a.aligned() != b.aligned()) {
1003 for (int c = 0; c < a.planes(); ++c) {
1004 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]) {
1008 uint8_t* p = a.data()[c];
1009 uint8_t* q = b.data()[c];
1010 int const lines = a.sample_size(c).height;
1011 for (int y = 0; y < lines; ++y) {
1012 if (memcmp (p, q, a.line_size()[c]) != 0) {
1025 * @param f Amount to fade by; 0 is black, 1 is no fade.
1028 Image::fade (float f)
1030 switch (_pixel_format) {
1031 case AV_PIX_FMT_YUV420P:
1032 case AV_PIX_FMT_YUV422P:
1033 case AV_PIX_FMT_YUV444P:
1034 case AV_PIX_FMT_YUV411P:
1035 case AV_PIX_FMT_YUVJ420P:
1036 case AV_PIX_FMT_YUVJ422P:
1037 case AV_PIX_FMT_YUVJ444P:
1038 case AV_PIX_FMT_RGB24:
1039 case AV_PIX_FMT_ARGB:
1040 case AV_PIX_FMT_RGBA:
1041 case AV_PIX_FMT_ABGR:
1042 case AV_PIX_FMT_BGRA:
1043 case AV_PIX_FMT_RGB555LE:
1045 for (int c = 0; c < 3; ++c) {
1046 uint8_t* p = data()[c];
1047 int const lines = sample_size(c).height;
1048 for (int y = 0; y < lines; ++y) {
1050 for (int x = 0; x < line_size()[c]; ++x) {
1051 *q = int (float (*q) * f);
1059 case AV_PIX_FMT_YUV422P9LE:
1060 case AV_PIX_FMT_YUV444P9LE:
1061 case AV_PIX_FMT_YUV422P10LE:
1062 case AV_PIX_FMT_YUV444P10LE:
1063 case AV_PIX_FMT_YUV422P16LE:
1064 case AV_PIX_FMT_YUV444P16LE:
1065 case AV_PIX_FMT_YUVA420P9LE:
1066 case AV_PIX_FMT_YUVA422P9LE:
1067 case AV_PIX_FMT_YUVA444P9LE:
1068 case AV_PIX_FMT_YUVA420P10LE:
1069 case AV_PIX_FMT_YUVA422P10LE:
1070 case AV_PIX_FMT_YUVA444P10LE:
1071 case AV_PIX_FMT_RGB48LE:
1072 case AV_PIX_FMT_XYZ12LE:
1073 /* 16-bit little-endian */
1074 for (int c = 0; c < 3; ++c) {
1075 int const stride_pixels = stride()[c] / 2;
1076 int const line_size_pixels = line_size()[c] / 2;
1077 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1078 int const lines = sample_size(c).height;
1079 for (int y = 0; y < lines; ++y) {
1081 for (int x = 0; x < line_size_pixels; ++x) {
1082 *q = int (float (*q) * f);
1090 case AV_PIX_FMT_YUV422P9BE:
1091 case AV_PIX_FMT_YUV444P9BE:
1092 case AV_PIX_FMT_YUV444P10BE:
1093 case AV_PIX_FMT_YUV422P10BE:
1094 case AV_PIX_FMT_YUVA420P9BE:
1095 case AV_PIX_FMT_YUVA422P9BE:
1096 case AV_PIX_FMT_YUVA444P9BE:
1097 case AV_PIX_FMT_YUVA420P10BE:
1098 case AV_PIX_FMT_YUVA422P10BE:
1099 case AV_PIX_FMT_YUVA444P10BE:
1100 case AV_PIX_FMT_YUVA420P16BE:
1101 case AV_PIX_FMT_YUVA422P16BE:
1102 case AV_PIX_FMT_YUVA444P16BE:
1103 case AV_PIX_FMT_RGB48BE:
1104 /* 16-bit big-endian */
1105 for (int c = 0; c < 3; ++c) {
1106 int const stride_pixels = stride()[c] / 2;
1107 int const line_size_pixels = line_size()[c] / 2;
1108 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1109 int const lines = sample_size(c).height;
1110 for (int y = 0; y < lines; ++y) {
1112 for (int x = 0; x < line_size_pixels; ++x) {
1113 *q = swap_16 (int (float (swap_16 (*q)) * f));
1121 case AV_PIX_FMT_UYVY422:
1123 int const Y = sample_size(0).height;
1124 int const X = line_size()[0];
1125 uint8_t* p = data()[0];
1126 for (int y = 0; y < Y; ++y) {
1127 for (int x = 0; x < X; ++x) {
1128 *p = int (float (*p) * f);
1136 throw PixelFormatError ("fade()", _pixel_format);
1140 shared_ptr<const Image>
1141 Image::ensure_aligned (shared_ptr<const Image> image)
1143 if (image->aligned()) {
1147 return shared_ptr<Image> (new Image (image, true));
1151 Image::memory_used () const
1154 for (int i = 0; i < planes(); ++i) {
1155 m += _stride[i] * sample_size(i).height;
1178 png_write_data (png_structp png_ptr, png_bytep data, png_size_t length)
1180 Memory* mem = reinterpret_cast<Memory*>(png_get_io_ptr(png_ptr));
1181 size_t size = mem->size + length;
1184 mem->data = reinterpret_cast<uint8_t*>(realloc(mem->data, size));
1186 mem->data = reinterpret_cast<uint8_t*>(malloc(size));
1190 throw EncodeError (N_("could not allocate memory for PNG"));
1193 memcpy (mem->data + mem->size, data, length);
1194 mem->size += length;
1198 png_flush (png_structp)
1204 png_error_fn (png_structp png_ptr, char const * message)
1206 reinterpret_cast<Image*>(png_get_error_ptr(png_ptr))->png_error (message);
1210 Image::png_error (char const * message)
1212 throw EncodeError (String::compose ("Error during PNG write: %1", message));
1216 Image::as_png () const
1218 DCPOMATIC_ASSERT (bytes_per_pixel(0) == 4);
1219 DCPOMATIC_ASSERT (planes() == 1);
1220 DCPOMATIC_ASSERT (pixel_format() == AV_PIX_FMT_BGRA);
1222 /* error handling? */
1223 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, reinterpret_cast<void*>(const_cast<Image*>(this)), png_error_fn, 0);
1225 throw EncodeError (N_("could not create PNG write struct"));
1230 png_set_write_fn (png_ptr, &state, png_write_data, png_flush);
1232 png_infop info_ptr = png_create_info_struct(png_ptr);
1234 png_destroy_write_struct (&png_ptr, &info_ptr);
1235 throw EncodeError (N_("could not create PNG info struct"));
1238 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);
1240 png_byte ** row_pointers = reinterpret_cast<png_byte **>(png_malloc(png_ptr, size().height * sizeof(png_byte *)));
1241 for (int i = 0; i < size().height; ++i) {
1242 row_pointers[i] = (png_byte *) (data()[0] + i * stride()[0]);
1245 png_write_info (png_ptr, info_ptr);
1246 png_write_image (png_ptr, row_pointers);
1247 png_write_end (png_ptr, info_ptr);
1249 png_destroy_write_struct (&png_ptr, &info_ptr);
1250 png_free (png_ptr, row_pointers);
1252 return dcp::Data (state.data, state.size);