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 "dcpomatic_socket.h"
31 #include <dcp/rgb_xyz.h>
32 #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>
40 #if HAVE_VALGRIND_MEMCHECK_H
41 #include <valgrind/memcheck.h>
53 using std::runtime_error;
54 using boost::shared_ptr;
58 Image::vertical_factor (int n) const
64 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
66 throw PixelFormatError ("line_factor()", _pixel_format);
69 return pow (2.0f, d->log2_chroma_h);
73 Image::horizontal_factor (int n) const
79 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
81 throw PixelFormatError ("sample_size()", _pixel_format);
84 return pow (2.0f, d->log2_chroma_w);
87 /** @param n Component index.
88 * @return Number of samples (i.e. pixels, unless sub-sampled) in each direction for this component.
91 Image::sample_size (int n) const
94 lrint (ceil (static_cast<double>(size().width) / horizontal_factor (n))),
95 lrint (ceil (static_cast<double>(size().height) / vertical_factor (n)))
99 /** @return Number of planes */
101 Image::planes () const
103 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
105 throw PixelFormatError ("planes()", _pixel_format);
108 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
112 return d->nb_components;
115 /** Crop this image, scale it to `inter_size' and then place it in a black frame of `out_size'.
116 * @param crop Amount to crop by.
117 * @param inter_size Size to scale the cropped image to.
118 * @param out_size Size of output frame; if this is larger than inter_size there will be black padding.
119 * @param yuv_to_rgb YUV to RGB transformation to use, if required.
120 * @param out_format Output pixel format.
121 * @param out_aligned true to make the output image aligned.
122 * @param fast Try to be fast at the possible expense of quality; at present this means using
123 * fast bilinear rather than bicubic scaling.
126 Image::crop_scale_window (
127 Crop crop, dcp::Size inter_size, dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast
130 /* Empirical testing suggests that sws_scale() will crash if
131 the input image is not aligned.
133 DCPOMATIC_ASSERT (aligned ());
135 DCPOMATIC_ASSERT (out_size.width >= inter_size.width);
136 DCPOMATIC_ASSERT (out_size.height >= inter_size.height);
138 /* Here's an image of out_size. Below we may write to it starting at an offset so we get some padding.
139 Hence we want to write in the following pattern:
141 block start write start line end
142 |..(padding)..|<------line-size------------->|..(padding)..|
143 |..(padding)..|<------line-size------------->|..(padding)..|
144 |..(padding)..|<------line-size------------->|..(padding)..|
146 where line-size is of the smaller (inter_size) image and the full padded line length is that of
147 out_size. To get things to work we have to tell FFmpeg that the stride is that of out_size.
148 However some parts of FFmpeg (notably rgb48Toxyz12 in swscale.c) process data for the full
149 specified *stride*. This does not matter until we get to the last line:
151 block start write start line end
152 |..(padding)..|<------line-size------------->|XXXwrittenXXX|
153 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXX|
154 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXXXXXwrittenXXX
157 To get around this, we ask Image to overallocate its buffers by the overrun.
160 shared_ptr<Image> out (new Image (out_format, out_size, out_aligned, (out_size.width - inter_size.width) / 2));
163 /* Size of the image after any crop */
164 dcp::Size const cropped_size = crop.apply (size ());
166 /* Scale context for a scale from cropped_size to inter_size */
167 struct SwsContext* scale_context = sws_getContext (
168 cropped_size.width, cropped_size.height, pixel_format(),
169 inter_size.width, inter_size.height, out_format,
170 fast ? SWS_FAST_BILINEAR : SWS_BICUBIC, 0, 0, 0
173 if (!scale_context) {
174 throw runtime_error (N_("Could not allocate SwsContext"));
177 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
178 int const lut[dcp::YUV_TO_RGB_COUNT] = {
183 sws_setColorspaceDetails (
185 sws_getCoefficients (lut[yuv_to_rgb]), 0,
186 sws_getCoefficients (lut[yuv_to_rgb]), 0,
190 AVPixFmtDescriptor const * in_desc = av_pix_fmt_desc_get (_pixel_format);
192 throw PixelFormatError ("crop_scale_window()", _pixel_format);
195 /* Prepare input data pointers with crop */
196 uint8_t* scale_in_data[planes()];
197 for (int c = 0; c < planes(); ++c) {
198 /* To work out the crop in bytes, start by multiplying
199 the crop by the (average) bytes per pixel. Then
200 round down so that we don't crop a subsampled pixel until
201 we've cropped all of its Y-channel pixels.
203 int const x = lrintf (bytes_per_pixel(c) * crop.left) & ~ ((int) in_desc->log2_chroma_w);
204 scale_in_data[c] = data()[c] + x + stride()[c] * (crop.top / vertical_factor(c));
207 /* Corner of the image within out_size */
208 Position<int> const corner ((out_size.width - inter_size.width) / 2, (out_size.height - inter_size.height) / 2);
210 AVPixFmtDescriptor const * out_desc = av_pix_fmt_desc_get (out_format);
212 throw PixelFormatError ("crop_scale_window()", out_format);
215 uint8_t* scale_out_data[out->planes()];
216 for (int c = 0; c < out->planes(); ++c) {
217 /* See the note in the crop loop above */
218 int const x = lrintf (out->bytes_per_pixel(c) * corner.x) & ~ ((int) out_desc->log2_chroma_w);
219 scale_out_data[c] = out->data()[c] + x + out->stride()[c] * (corner.y / out->vertical_factor(c));
224 scale_in_data, stride(),
225 0, cropped_size.height,
226 scale_out_data, out->stride()
229 sws_freeContext (scale_context);
235 Image::convert_pixel_format (dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
237 return scale(size(), yuv_to_rgb, out_format, out_aligned, fast);
240 /** @param out_size Size to scale to.
241 * @param yuv_to_rgb YUVToRGB transform transform to use, if required.
242 * @param out_format Output pixel format.
243 * @param out_aligned true to make an aligned output image.
244 * @param fast Try to be fast at the possible expense of quality; at present this means using
245 * fast bilinear rather than bicubic scaling.
248 Image::scale (dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
250 /* Empirical testing suggests that sws_scale() will crash if
251 the input image is not aligned.
253 DCPOMATIC_ASSERT (aligned ());
255 shared_ptr<Image> scaled (new Image (out_format, out_size, out_aligned));
257 struct SwsContext* scale_context = sws_getContext (
258 size().width, size().height, pixel_format(),
259 out_size.width, out_size.height, out_format,
260 (fast ? SWS_FAST_BILINEAR : SWS_BICUBIC) | SWS_ACCURATE_RND, 0, 0, 0
263 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
264 int const lut[dcp::YUV_TO_RGB_COUNT] = {
269 sws_setColorspaceDetails (
271 sws_getCoefficients (lut[yuv_to_rgb]), 0,
272 sws_getCoefficients (lut[yuv_to_rgb]), 0,
280 scaled->data(), scaled->stride()
283 sws_freeContext (scale_context);
288 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
290 Image::yuv_16_black (uint16_t v, bool alpha)
292 memset (data()[0], 0, sample_size(0).height * stride()[0]);
293 for (int i = 1; i < 3; ++i) {
294 int16_t* p = reinterpret_cast<int16_t*> (data()[i]);
295 int const lines = sample_size(i).height;
296 for (int y = 0; y < lines; ++y) {
297 /* We divide by 2 here because we are writing 2 bytes at a time */
298 for (int x = 0; x < line_size()[i] / 2; ++x) {
301 p += stride()[i] / 2;
306 memset (data()[3], 0, sample_size(3).height * stride()[3]);
311 Image::swap_16 (uint16_t v)
313 return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
319 /* U/V black value for 8-bit colour */
320 static uint8_t const eight_bit_uv = (1 << 7) - 1;
321 /* U/V black value for 9-bit colour */
322 static uint16_t const nine_bit_uv = (1 << 8) - 1;
323 /* U/V black value for 10-bit colour */
324 static uint16_t const ten_bit_uv = (1 << 9) - 1;
325 /* U/V black value for 16-bit colour */
326 static uint16_t const sixteen_bit_uv = (1 << 15) - 1;
328 switch (_pixel_format) {
329 case AV_PIX_FMT_YUV420P:
330 case AV_PIX_FMT_YUV422P:
331 case AV_PIX_FMT_YUV444P:
332 case AV_PIX_FMT_YUV411P:
333 memset (data()[0], 0, sample_size(0).height * stride()[0]);
334 memset (data()[1], eight_bit_uv, sample_size(1).height * stride()[1]);
335 memset (data()[2], eight_bit_uv, sample_size(2).height * stride()[2]);
338 case AV_PIX_FMT_YUVJ420P:
339 case AV_PIX_FMT_YUVJ422P:
340 case AV_PIX_FMT_YUVJ444P:
341 memset (data()[0], 0, sample_size(0).height * stride()[0]);
342 memset (data()[1], eight_bit_uv + 1, sample_size(1).height * stride()[1]);
343 memset (data()[2], eight_bit_uv + 1, sample_size(2).height * stride()[2]);
346 case AV_PIX_FMT_YUV422P9LE:
347 case AV_PIX_FMT_YUV444P9LE:
348 yuv_16_black (nine_bit_uv, false);
351 case AV_PIX_FMT_YUV422P9BE:
352 case AV_PIX_FMT_YUV444P9BE:
353 yuv_16_black (swap_16 (nine_bit_uv), false);
356 case AV_PIX_FMT_YUV422P10LE:
357 case AV_PIX_FMT_YUV444P10LE:
358 yuv_16_black (ten_bit_uv, false);
361 case AV_PIX_FMT_YUV422P16LE:
362 case AV_PIX_FMT_YUV444P16LE:
363 yuv_16_black (sixteen_bit_uv, false);
366 case AV_PIX_FMT_YUV444P10BE:
367 case AV_PIX_FMT_YUV422P10BE:
368 yuv_16_black (swap_16 (ten_bit_uv), false);
371 case AV_PIX_FMT_YUVA420P9BE:
372 case AV_PIX_FMT_YUVA422P9BE:
373 case AV_PIX_FMT_YUVA444P9BE:
374 yuv_16_black (swap_16 (nine_bit_uv), true);
377 case AV_PIX_FMT_YUVA420P9LE:
378 case AV_PIX_FMT_YUVA422P9LE:
379 case AV_PIX_FMT_YUVA444P9LE:
380 yuv_16_black (nine_bit_uv, true);
383 case AV_PIX_FMT_YUVA420P10BE:
384 case AV_PIX_FMT_YUVA422P10BE:
385 case AV_PIX_FMT_YUVA444P10BE:
386 yuv_16_black (swap_16 (ten_bit_uv), true);
389 case AV_PIX_FMT_YUVA420P10LE:
390 case AV_PIX_FMT_YUVA422P10LE:
391 case AV_PIX_FMT_YUVA444P10LE:
392 yuv_16_black (ten_bit_uv, true);
395 case AV_PIX_FMT_YUVA420P16BE:
396 case AV_PIX_FMT_YUVA422P16BE:
397 case AV_PIX_FMT_YUVA444P16BE:
398 yuv_16_black (swap_16 (sixteen_bit_uv), true);
401 case AV_PIX_FMT_YUVA420P16LE:
402 case AV_PIX_FMT_YUVA422P16LE:
403 case AV_PIX_FMT_YUVA444P16LE:
404 yuv_16_black (sixteen_bit_uv, true);
407 case AV_PIX_FMT_RGB24:
408 case AV_PIX_FMT_ARGB:
409 case AV_PIX_FMT_RGBA:
410 case AV_PIX_FMT_ABGR:
411 case AV_PIX_FMT_BGRA:
412 case AV_PIX_FMT_RGB555LE:
413 case AV_PIX_FMT_RGB48LE:
414 case AV_PIX_FMT_RGB48BE:
415 case AV_PIX_FMT_XYZ12LE:
416 memset (data()[0], 0, sample_size(0).height * stride()[0]);
419 case AV_PIX_FMT_UYVY422:
421 int const Y = sample_size(0).height;
422 int const X = line_size()[0];
423 uint8_t* p = data()[0];
424 for (int y = 0; y < Y; ++y) {
425 for (int x = 0; x < X / 4; ++x) {
426 *p++ = eight_bit_uv; // Cb
428 *p++ = eight_bit_uv; // Cr
436 throw PixelFormatError ("make_black()", _pixel_format);
441 Image::make_transparent ()
443 if (_pixel_format != AV_PIX_FMT_BGRA) {
444 throw PixelFormatError ("make_transparent()", _pixel_format);
447 memset (data()[0], 0, sample_size(0).height * stride()[0]);
451 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
453 /* We're blending BGRA images; first byte is blue, second byte is green, third byte red, fourth byte alpha */
454 DCPOMATIC_ASSERT (other->pixel_format() == AV_PIX_FMT_BGRA);
455 int const other_bpp = 4;
457 int start_tx = position.x;
461 start_ox = -start_tx;
465 int start_ty = position.y;
469 start_oy = -start_ty;
473 switch (_pixel_format) {
474 case AV_PIX_FMT_RGB24:
476 /* Going onto RGB24. First byte is red, second green, third blue */
477 int const this_bpp = 3;
478 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
479 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
480 uint8_t* op = other->data()[0] + oy * other->stride()[0];
481 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
482 float const alpha = float (op[3]) / 255;
483 tp[0] = op[2] * alpha + tp[0] * (1 - alpha);
484 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
485 tp[2] = op[0] * alpha + tp[2] * (1 - alpha);
493 case AV_PIX_FMT_BGRA:
495 int const this_bpp = 4;
496 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
497 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
498 uint8_t* op = other->data()[0] + oy * other->stride()[0];
499 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
500 float const alpha = float (op[3]) / 255;
501 tp[0] = op[0] * alpha + tp[0] * (1 - alpha);
502 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
503 tp[2] = op[2] * alpha + tp[2] * (1 - alpha);
504 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
512 case AV_PIX_FMT_RGBA:
514 int const this_bpp = 4;
515 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
516 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
517 uint8_t* op = other->data()[0] + oy * other->stride()[0];
518 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
519 float const alpha = float (op[3]) / 255;
520 tp[0] = op[2] * alpha + tp[0] * (1 - alpha);
521 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
522 tp[2] = op[0] * alpha + tp[2] * (1 - alpha);
523 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
531 case AV_PIX_FMT_RGB48LE:
533 int const this_bpp = 6;
534 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
535 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
536 uint8_t* op = other->data()[0] + oy * other->stride()[0];
537 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
538 float const alpha = float (op[3]) / 255;
539 /* Blend high bytes */
540 tp[1] = op[2] * alpha + tp[1] * (1 - alpha);
541 tp[3] = op[1] * alpha + tp[3] * (1 - alpha);
542 tp[5] = op[0] * alpha + tp[5] * (1 - alpha);
550 case AV_PIX_FMT_XYZ12LE:
552 dcp::ColourConversion conv = dcp::ColourConversion::srgb_to_xyz();
553 double fast_matrix[9];
554 dcp::combined_rgb_to_xyz (conv, fast_matrix);
555 double const * lut_in = conv.in()->lut (8, false);
556 double const * lut_out = conv.out()->lut (16, true);
557 int const this_bpp = 6;
558 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
559 uint16_t* tp = reinterpret_cast<uint16_t*> (data()[0] + ty * stride()[0] + start_tx * this_bpp);
560 uint8_t* op = other->data()[0] + oy * other->stride()[0];
561 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
562 float const alpha = float (op[3]) / 255;
564 /* Convert sRGB to XYZ; op is BGRA. First, input gamma LUT */
565 double const r = lut_in[op[2]];
566 double const g = lut_in[op[1]];
567 double const b = lut_in[op[0]];
569 /* RGB to XYZ, including Bradford transform and DCI companding */
570 double const x = max (0.0, min (65535.0, r * fast_matrix[0] + g * fast_matrix[1] + b * fast_matrix[2]));
571 double const y = max (0.0, min (65535.0, r * fast_matrix[3] + g * fast_matrix[4] + b * fast_matrix[5]));
572 double const z = max (0.0, min (65535.0, r * fast_matrix[6] + g * fast_matrix[7] + b * fast_matrix[8]));
574 /* Out gamma LUT and blend */
575 tp[0] = lrint(lut_out[lrint(x)] * 65535) * alpha + tp[0] * (1 - alpha);
576 tp[1] = lrint(lut_out[lrint(y)] * 65535) * alpha + tp[1] * (1 - alpha);
577 tp[2] = lrint(lut_out[lrint(z)] * 65535) * alpha + tp[2] * (1 - alpha);
585 case AV_PIX_FMT_YUV420P:
587 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
588 dcp::Size const ts = size();
589 dcp::Size const os = yuv->size();
590 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
591 int const hty = ty / 2;
592 int const hoy = oy / 2;
593 uint8_t* tY = data()[0] + (ty * stride()[0]) + start_tx;
594 uint8_t* tU = data()[1] + (hty * stride()[1]) + start_tx / 2;
595 uint8_t* tV = data()[2] + (hty * stride()[2]) + start_tx / 2;
596 uint8_t* oY = yuv->data()[0] + (oy * yuv->stride()[0]) + start_ox;
597 uint8_t* oU = yuv->data()[1] + (hoy * yuv->stride()[1]) + start_ox / 2;
598 uint8_t* oV = yuv->data()[2] + (hoy * yuv->stride()[2]) + start_ox / 2;
599 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
600 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
601 float const a = float(alpha[3]) / 255;
602 *tY = *oY * a + *tY * (1 - a);
603 *tU = *oU * a + *tU * (1 - a);
604 *tV = *oV * a + *tV * (1 - a);
620 case AV_PIX_FMT_YUV420P10:
622 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
623 dcp::Size const ts = size();
624 dcp::Size const os = yuv->size();
625 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
626 int const hty = ty / 2;
627 int const hoy = oy / 2;
628 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
629 uint16_t* tU = ((uint16_t *) (data()[1] + (hty * stride()[1]))) + start_tx / 2;
630 uint16_t* tV = ((uint16_t *) (data()[2] + (hty * stride()[2]))) + start_tx / 2;
631 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
632 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (hoy * yuv->stride()[1]))) + start_ox / 2;
633 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (hoy * yuv->stride()[2]))) + start_ox / 2;
634 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
635 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
636 float const a = float(alpha[3]) / 255;
637 *tY = *oY * a + *tY * (1 - a);
638 *tU = *oU * a + *tU * (1 - a);
639 *tV = *oV * a + *tV * (1 - a);
655 case AV_PIX_FMT_YUV422P10LE:
657 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
658 dcp::Size const ts = size();
659 dcp::Size const os = yuv->size();
660 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
661 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
662 uint16_t* tU = ((uint16_t *) (data()[1] + (ty * stride()[1]))) + start_tx / 2;
663 uint16_t* tV = ((uint16_t *) (data()[2] + (ty * stride()[2]))) + start_tx / 2;
664 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
665 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (oy * yuv->stride()[1]))) + start_ox / 2;
666 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (oy * yuv->stride()[2]))) + start_ox / 2;
667 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
668 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
669 float const a = float(alpha[3]) / 255;
670 *tY = *oY * a + *tY * (1 - a);
671 *tU = *oU * a + *tU * (1 - a);
672 *tV = *oV * a + *tV * (1 - a);
689 throw PixelFormatError ("alpha_blend()", _pixel_format);
694 Image::copy (shared_ptr<const Image> other, Position<int> position)
696 /* Only implemented for RGB24 onto RGB24 so far */
697 DCPOMATIC_ASSERT (_pixel_format == AV_PIX_FMT_RGB24 && other->pixel_format() == AV_PIX_FMT_RGB24);
698 DCPOMATIC_ASSERT (position.x >= 0 && position.y >= 0);
700 int const N = min (position.x + other->size().width, size().width) - position.x;
701 for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
702 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
703 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
704 memcpy (tp, op, N * 3);
709 Image::read_from_socket (shared_ptr<Socket> socket)
711 for (int i = 0; i < planes(); ++i) {
712 uint8_t* p = data()[i];
713 int const lines = sample_size(i).height;
714 for (int y = 0; y < lines; ++y) {
715 socket->read (p, line_size()[i]);
722 Image::write_to_socket (shared_ptr<Socket> socket) const
724 for (int i = 0; i < planes(); ++i) {
725 uint8_t* p = data()[i];
726 int const lines = sample_size(i).height;
727 for (int y = 0; y < lines; ++y) {
728 socket->write (p, line_size()[i]);
735 Image::bytes_per_pixel (int c) const
737 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
739 throw PixelFormatError ("bytes_per_pixel()", _pixel_format);
746 float bpp[4] = { 0, 0, 0, 0 };
748 #ifdef DCPOMATIC_HAVE_AVCOMPONENTDESCRIPTOR_DEPTH_MINUS1
749 bpp[0] = floor ((d->comp[0].depth_minus1 + 8) / 8);
750 if (d->nb_components > 1) {
751 bpp[1] = floor ((d->comp[1].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
753 if (d->nb_components > 2) {
754 bpp[2] = floor ((d->comp[2].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
756 if (d->nb_components > 3) {
757 bpp[3] = floor ((d->comp[3].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
760 bpp[0] = floor ((d->comp[0].depth + 7) / 8);
761 if (d->nb_components > 1) {
762 bpp[1] = floor ((d->comp[1].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
764 if (d->nb_components > 2) {
765 bpp[2] = floor ((d->comp[2].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
767 if (d->nb_components > 3) {
768 bpp[3] = floor ((d->comp[3].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
772 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
773 /* Not planar; sum them up */
774 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
780 /** Construct a Image of a given size and format, allocating memory
783 * @param p Pixel format.
784 * @param s Size in pixels.
785 * @param aligned true to make each row of this image aligned to a 32-byte boundary.
786 * @param extra_pixels Amount of extra "run-off" memory to allocate at the end of each plane in pixels.
788 Image::Image (AVPixelFormat p, dcp::Size s, bool aligned, int extra_pixels)
792 , _extra_pixels (extra_pixels)
797 /** Construct an Image from some PNG data */
798 Image::Image (dcp::Data png)
801 blob.update (png.data().get(), png.size());
802 Magick::Image* magick_image = new Magick::Image (blob);
803 _size = dcp::Size(magick_image->columns(), magick_image->rows());
804 _pixel_format = AV_PIX_FMT_BGRA;
809 /* Write line-by-line here as _image must be aligned, and write() cannot be told about strides */
810 uint8_t* p = data()[0];
811 for (int i = 0; i < _size.height; ++i) {
812 #ifdef DCPOMATIC_HAVE_MAGICKCORE_NAMESPACE
813 using namespace MagickCore;
815 #ifdef DCPOMATIC_HAVE_MAGICKLIB_NAMESPACE
816 using namespace MagickLib;
818 magick_image->write (0, i, _size.width, 1, "BGRA", CharPixel, p);
828 _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
829 _data[0] = _data[1] = _data[2] = _data[3] = 0;
831 _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
832 _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
834 _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
835 _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
837 for (int i = 0; i < planes(); ++i) {
838 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
839 _stride[i] = stride_round_up (i, _line_size, _aligned ? 32 : 1);
841 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
842 uses a 16-byte fetch to read three bytes (R/G/B) of image data.
843 Hence on the last pixel of the last line it reads over the end of
844 the actual data by 1 byte. If the width of an image is a multiple
845 of the stride alignment there will be no padding at the end of image lines.
846 OS X crashes on this illegal read, though other operating systems don't
847 seem to mind. The nasty + 1 in this malloc makes sure there is always a byte
848 for that instruction to read safely.
850 Further to the above, valgrind is now telling me that ff_rgb24ToY_ssse3
851 over-reads by more then _avx. I can't follow the code to work out how much,
852 so I'll just over-allocate by 32 bytes and have done with it. Empirical
853 testing suggests that it works.
855 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * sample_size(i).height + _extra_pixels * bytes_per_pixel(i) + 32);
856 #if HAVE_VALGRIND_MEMCHECK_H
857 /* The data between the end of the line size and the stride is undefined but processed by
858 libswscale, causing lots of valgrind errors. Mark it all defined to quell these errors.
860 VALGRIND_MAKE_MEM_DEFINED (_data[i], _stride[i] * sample_size(i).height + _extra_pixels * bytes_per_pixel(i) + 32);
865 Image::Image (Image const & other)
866 : boost::enable_shared_from_this<Image>(other)
867 , _size (other._size)
868 , _pixel_format (other._pixel_format)
869 , _aligned (other._aligned)
870 , _extra_pixels (other._extra_pixels)
874 for (int i = 0; i < planes(); ++i) {
875 uint8_t* p = _data[i];
876 uint8_t* q = other._data[i];
877 int const lines = sample_size(i).height;
878 for (int j = 0; j < lines; ++j) {
879 memcpy (p, q, _line_size[i]);
881 q += other.stride()[i];
886 Image::Image (AVFrame* frame)
887 : _size (frame->width, frame->height)
888 , _pixel_format (static_cast<AVPixelFormat> (frame->format))
894 for (int i = 0; i < planes(); ++i) {
895 uint8_t* p = _data[i];
896 uint8_t* q = frame->data[i];
897 int const lines = sample_size(i).height;
898 for (int j = 0; j < lines; ++j) {
899 memcpy (p, q, _line_size[i]);
901 /* AVFrame's linesize is what we call `stride' */
902 q += frame->linesize[i];
907 Image::Image (shared_ptr<const Image> other, bool aligned)
908 : _size (other->_size)
909 , _pixel_format (other->_pixel_format)
911 , _extra_pixels (other->_extra_pixels)
915 for (int i = 0; i < planes(); ++i) {
916 DCPOMATIC_ASSERT (line_size()[i] == other->line_size()[i]);
917 uint8_t* p = _data[i];
918 uint8_t* q = other->data()[i];
919 int const lines = sample_size(i).height;
920 for (int j = 0; j < lines; ++j) {
921 memcpy (p, q, line_size()[i]);
923 q += other->stride()[i];
929 Image::operator= (Image const & other)
931 if (this == &other) {
941 Image::swap (Image & other)
943 std::swap (_size, other._size);
944 std::swap (_pixel_format, other._pixel_format);
946 for (int i = 0; i < 4; ++i) {
947 std::swap (_data[i], other._data[i]);
948 std::swap (_line_size[i], other._line_size[i]);
949 std::swap (_stride[i], other._stride[i]);
952 std::swap (_aligned, other._aligned);
953 std::swap (_extra_pixels, other._extra_pixels);
956 /** Destroy a Image */
959 for (int i = 0; i < planes(); ++i) {
964 av_free (_line_size);
975 Image::line_size () const
981 Image::stride () const
993 Image::aligned () const
999 merge (list<PositionImage> images)
1001 if (images.empty ()) {
1002 return PositionImage ();
1005 if (images.size() == 1) {
1006 return images.front ();
1009 dcpomatic::Rect<int> all (images.front().position, images.front().image->size().width, images.front().image->size().height);
1010 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1011 all.extend (dcpomatic::Rect<int> (i->position, i->image->size().width, i->image->size().height));
1014 shared_ptr<Image> merged (new Image (images.front().image->pixel_format (), dcp::Size (all.width, all.height), true));
1015 merged->make_transparent ();
1016 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1017 merged->alpha_blend (i->image, i->position - all.position());
1020 return PositionImage (merged, all.position ());
1024 operator== (Image const & a, Image const & b)
1026 if (a.planes() != b.planes() || a.pixel_format() != b.pixel_format() || a.aligned() != b.aligned()) {
1030 for (int c = 0; c < a.planes(); ++c) {
1031 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]) {
1035 uint8_t* p = a.data()[c];
1036 uint8_t* q = b.data()[c];
1037 int const lines = a.sample_size(c).height;
1038 for (int y = 0; y < lines; ++y) {
1039 if (memcmp (p, q, a.line_size()[c]) != 0) {
1052 * @param f Amount to fade by; 0 is black, 1 is no fade.
1055 Image::fade (float f)
1057 switch (_pixel_format) {
1058 case AV_PIX_FMT_YUV420P:
1059 case AV_PIX_FMT_YUV422P:
1060 case AV_PIX_FMT_YUV444P:
1061 case AV_PIX_FMT_YUV411P:
1062 case AV_PIX_FMT_YUVJ420P:
1063 case AV_PIX_FMT_YUVJ422P:
1064 case AV_PIX_FMT_YUVJ444P:
1065 case AV_PIX_FMT_RGB24:
1066 case AV_PIX_FMT_ARGB:
1067 case AV_PIX_FMT_RGBA:
1068 case AV_PIX_FMT_ABGR:
1069 case AV_PIX_FMT_BGRA:
1070 case AV_PIX_FMT_RGB555LE:
1072 for (int c = 0; c < 3; ++c) {
1073 uint8_t* p = data()[c];
1074 int const lines = sample_size(c).height;
1075 for (int y = 0; y < lines; ++y) {
1077 for (int x = 0; x < line_size()[c]; ++x) {
1078 *q = int (float (*q) * f);
1086 case AV_PIX_FMT_YUV422P9LE:
1087 case AV_PIX_FMT_YUV444P9LE:
1088 case AV_PIX_FMT_YUV422P10LE:
1089 case AV_PIX_FMT_YUV444P10LE:
1090 case AV_PIX_FMT_YUV422P16LE:
1091 case AV_PIX_FMT_YUV444P16LE:
1092 case AV_PIX_FMT_YUVA420P9LE:
1093 case AV_PIX_FMT_YUVA422P9LE:
1094 case AV_PIX_FMT_YUVA444P9LE:
1095 case AV_PIX_FMT_YUVA420P10LE:
1096 case AV_PIX_FMT_YUVA422P10LE:
1097 case AV_PIX_FMT_YUVA444P10LE:
1098 case AV_PIX_FMT_RGB48LE:
1099 case AV_PIX_FMT_XYZ12LE:
1100 /* 16-bit little-endian */
1101 for (int c = 0; c < 3; ++c) {
1102 int const stride_pixels = stride()[c] / 2;
1103 int const line_size_pixels = line_size()[c] / 2;
1104 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1105 int const lines = sample_size(c).height;
1106 for (int y = 0; y < lines; ++y) {
1108 for (int x = 0; x < line_size_pixels; ++x) {
1109 *q = int (float (*q) * f);
1117 case AV_PIX_FMT_YUV422P9BE:
1118 case AV_PIX_FMT_YUV444P9BE:
1119 case AV_PIX_FMT_YUV444P10BE:
1120 case AV_PIX_FMT_YUV422P10BE:
1121 case AV_PIX_FMT_YUVA420P9BE:
1122 case AV_PIX_FMT_YUVA422P9BE:
1123 case AV_PIX_FMT_YUVA444P9BE:
1124 case AV_PIX_FMT_YUVA420P10BE:
1125 case AV_PIX_FMT_YUVA422P10BE:
1126 case AV_PIX_FMT_YUVA444P10BE:
1127 case AV_PIX_FMT_YUVA420P16BE:
1128 case AV_PIX_FMT_YUVA422P16BE:
1129 case AV_PIX_FMT_YUVA444P16BE:
1130 case AV_PIX_FMT_RGB48BE:
1131 /* 16-bit big-endian */
1132 for (int c = 0; c < 3; ++c) {
1133 int const stride_pixels = stride()[c] / 2;
1134 int const line_size_pixels = line_size()[c] / 2;
1135 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1136 int const lines = sample_size(c).height;
1137 for (int y = 0; y < lines; ++y) {
1139 for (int x = 0; x < line_size_pixels; ++x) {
1140 *q = swap_16 (int (float (swap_16 (*q)) * f));
1148 case AV_PIX_FMT_UYVY422:
1150 int const Y = sample_size(0).height;
1151 int const X = line_size()[0];
1152 uint8_t* p = data()[0];
1153 for (int y = 0; y < Y; ++y) {
1154 for (int x = 0; x < X; ++x) {
1155 *p = int (float (*p) * f);
1163 throw PixelFormatError ("fade()", _pixel_format);
1167 shared_ptr<const Image>
1168 Image::ensure_aligned (shared_ptr<const Image> image)
1170 if (image->aligned()) {
1174 return shared_ptr<Image> (new Image (image, true));
1178 Image::memory_used () const
1181 for (int i = 0; i < planes(); ++i) {
1182 m += _stride[i] * sample_size(i).height;
1188 Image::as_png () const
1190 #ifdef DCPOMATIC_IMAGE_MAGICK
1191 using namespace MagickCore;
1193 using namespace MagickLib;
1197 switch (_pixel_format) {
1198 case AV_PIX_FMT_RGB24:
1201 case AV_PIX_FMT_BGRA:
1205 DCPOMATIC_ASSERT (false);
1209 shared_ptr<const Image> use;
1211 use.reset (new Image(shared_from_this(), false));
1214 Magick::Image m (size().width, size().height, format, CharPixel, (void *) use->data()[0]);
1218 /* XXX: could use a subclass of Data here (storing its data in a Blob) */
1219 return dcp::Data (static_cast<const uint8_t*>(blob.data()), blob.length());