2 Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
4 This file is part of DCP-o-matic.
6 DCP-o-matic is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 DCP-o-matic is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
21 /** @file src/image.cc
22 * @brief A class to describe a video image.
26 #include "exceptions.h"
30 #include "compose.hpp"
31 #include "dcpomatic_socket.h"
32 #include <dcp/rgb_xyz.h>
33 #include <dcp/transfer_function.h>
35 #include <libswscale/swscale.h>
36 #include <libavutil/pixfmt.h>
37 #include <libavutil/pixdesc.h>
38 #include <libavutil/frame.h>
41 #if HAVE_VALGRIND_MEMCHECK_H
42 #include <valgrind/memcheck.h>
54 using std::runtime_error;
55 using boost::shared_ptr;
59 Image::vertical_factor (int n) const
65 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
67 throw PixelFormatError ("line_factor()", _pixel_format);
70 return pow (2.0f, d->log2_chroma_h);
74 Image::horizontal_factor (int n) const
80 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
82 throw PixelFormatError ("sample_size()", _pixel_format);
85 return pow (2.0f, d->log2_chroma_w);
88 /** @param n Component index.
89 * @return Number of samples (i.e. pixels, unless sub-sampled) in each direction for this component.
92 Image::sample_size (int n) const
95 lrint (ceil (static_cast<double>(size().width) / horizontal_factor (n))),
96 lrint (ceil (static_cast<double>(size().height) / vertical_factor (n)))
100 /** @return Number of planes */
102 Image::planes () const
104 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
106 throw PixelFormatError ("planes()", _pixel_format);
109 if (_pixel_format == AV_PIX_FMT_PAL8) {
113 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
117 return d->nb_components;
120 /** Crop this image, scale it to `inter_size' and then place it in a black frame of `out_size'.
121 * @param crop Amount to crop by.
122 * @param inter_size Size to scale the cropped image to.
123 * @param out_size Size of output frame; if this is larger than inter_size there will be black padding.
124 * @param yuv_to_rgb YUV to RGB transformation to use, if required.
125 * @param out_format Output pixel format.
126 * @param out_aligned true to make the output image aligned.
127 * @param fast Try to be fast at the possible expense of quality; at present this means using
128 * fast bilinear rather than bicubic scaling.
131 Image::crop_scale_window (
132 Crop crop, dcp::Size inter_size, dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast
135 /* Empirical testing suggests that sws_scale() will crash if
136 the input image is not aligned.
138 DCPOMATIC_ASSERT (aligned ());
140 DCPOMATIC_ASSERT (out_size.width >= inter_size.width);
141 DCPOMATIC_ASSERT (out_size.height >= inter_size.height);
143 /* Here's an image of out_size. Below we may write to it starting at an offset so we get some padding.
144 Hence we want to write in the following pattern:
146 block start write start line end
147 |..(padding)..|<------line-size------------->|..(padding)..|
148 |..(padding)..|<------line-size------------->|..(padding)..|
149 |..(padding)..|<------line-size------------->|..(padding)..|
151 where line-size is of the smaller (inter_size) image and the full padded line length is that of
152 out_size. To get things to work we have to tell FFmpeg that the stride is that of out_size.
153 However some parts of FFmpeg (notably rgb48Toxyz12 in swscale.c) process data for the full
154 specified *stride*. This does not matter until we get to the last line:
156 block start write start line end
157 |..(padding)..|<------line-size------------->|XXXwrittenXXX|
158 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXX|
159 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXXXXXwrittenXXX
162 To get around this, we ask Image to overallocate its buffers by the overrun.
165 shared_ptr<Image> out (new Image (out_format, out_size, out_aligned, (out_size.width - inter_size.width) / 2));
168 /* Size of the image after any crop */
169 dcp::Size const cropped_size = crop.apply (size ());
171 /* Scale context for a scale from cropped_size to inter_size */
172 struct SwsContext* scale_context = sws_getContext (
173 cropped_size.width, cropped_size.height, pixel_format(),
174 inter_size.width, inter_size.height, out_format,
175 fast ? SWS_FAST_BILINEAR : SWS_BICUBIC, 0, 0, 0
178 if (!scale_context) {
179 throw runtime_error (N_("Could not allocate SwsContext"));
182 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
183 int const lut[dcp::YUV_TO_RGB_COUNT] = {
188 sws_setColorspaceDetails (
190 sws_getCoefficients (lut[yuv_to_rgb]), 0,
191 sws_getCoefficients (lut[yuv_to_rgb]), 0,
195 AVPixFmtDescriptor const * in_desc = av_pix_fmt_desc_get (_pixel_format);
197 throw PixelFormatError ("crop_scale_window()", _pixel_format);
200 /* Prepare input data pointers with crop */
201 uint8_t* scale_in_data[planes()];
202 for (int c = 0; c < planes(); ++c) {
203 /* To work out the crop in bytes, start by multiplying
204 the crop by the (average) bytes per pixel. Then
205 round down so that we don't crop a subsampled pixel until
206 we've cropped all of its Y-channel pixels.
208 int const x = lrintf (bytes_per_pixel(c) * crop.left) & ~ ((int) in_desc->log2_chroma_w);
209 scale_in_data[c] = data()[c] + x + stride()[c] * (crop.top / vertical_factor(c));
212 /* Corner of the image within out_size */
213 Position<int> const corner ((out_size.width - inter_size.width) / 2, (out_size.height - inter_size.height) / 2);
215 AVPixFmtDescriptor const * out_desc = av_pix_fmt_desc_get (out_format);
217 throw PixelFormatError ("crop_scale_window()", out_format);
220 uint8_t* scale_out_data[out->planes()];
221 for (int c = 0; c < out->planes(); ++c) {
222 /* See the note in the crop loop above */
223 int const x = lrintf (out->bytes_per_pixel(c) * corner.x) & ~ ((int) out_desc->log2_chroma_w);
224 scale_out_data[c] = out->data()[c] + x + out->stride()[c] * (corner.y / out->vertical_factor(c));
229 scale_in_data, stride(),
230 0, cropped_size.height,
231 scale_out_data, out->stride()
234 sws_freeContext (scale_context);
240 Image::convert_pixel_format (dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
242 return scale(size(), yuv_to_rgb, out_format, out_aligned, fast);
245 /** @param out_size Size to scale to.
246 * @param yuv_to_rgb YUVToRGB transform transform to use, if required.
247 * @param out_format Output pixel format.
248 * @param out_aligned true to make an aligned output image.
249 * @param fast Try to be fast at the possible expense of quality; at present this means using
250 * fast bilinear rather than bicubic scaling.
253 Image::scale (dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
255 /* Empirical testing suggests that sws_scale() will crash if
256 the input image is not aligned.
258 DCPOMATIC_ASSERT (aligned ());
260 shared_ptr<Image> scaled (new Image (out_format, out_size, out_aligned));
262 struct SwsContext* scale_context = sws_getContext (
263 size().width, size().height, pixel_format(),
264 out_size.width, out_size.height, out_format,
265 (fast ? SWS_FAST_BILINEAR : SWS_BICUBIC) | SWS_ACCURATE_RND, 0, 0, 0
268 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
269 int const lut[dcp::YUV_TO_RGB_COUNT] = {
274 sws_setColorspaceDetails (
276 sws_getCoefficients (lut[yuv_to_rgb]), 0,
277 sws_getCoefficients (lut[yuv_to_rgb]), 0,
285 scaled->data(), scaled->stride()
288 sws_freeContext (scale_context);
293 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
295 Image::yuv_16_black (uint16_t v, bool alpha)
297 memset (data()[0], 0, sample_size(0).height * stride()[0]);
298 for (int i = 1; i < 3; ++i) {
299 int16_t* p = reinterpret_cast<int16_t*> (data()[i]);
300 int const lines = sample_size(i).height;
301 for (int y = 0; y < lines; ++y) {
302 /* We divide by 2 here because we are writing 2 bytes at a time */
303 for (int x = 0; x < line_size()[i] / 2; ++x) {
306 p += stride()[i] / 2;
311 memset (data()[3], 0, sample_size(3).height * stride()[3]);
316 Image::swap_16 (uint16_t v)
318 return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
324 /* U/V black value for 8-bit colour */
325 static uint8_t const eight_bit_uv = (1 << 7) - 1;
326 /* U/V black value for 9-bit colour */
327 static uint16_t const nine_bit_uv = (1 << 8) - 1;
328 /* U/V black value for 10-bit colour */
329 static uint16_t const ten_bit_uv = (1 << 9) - 1;
330 /* U/V black value for 16-bit colour */
331 static uint16_t const sixteen_bit_uv = (1 << 15) - 1;
333 switch (_pixel_format) {
334 case AV_PIX_FMT_YUV420P:
335 case AV_PIX_FMT_YUV422P:
336 case AV_PIX_FMT_YUV444P:
337 case AV_PIX_FMT_YUV411P:
338 memset (data()[0], 0, sample_size(0).height * stride()[0]);
339 memset (data()[1], eight_bit_uv, sample_size(1).height * stride()[1]);
340 memset (data()[2], eight_bit_uv, sample_size(2).height * stride()[2]);
343 case AV_PIX_FMT_YUVJ420P:
344 case AV_PIX_FMT_YUVJ422P:
345 case AV_PIX_FMT_YUVJ444P:
346 memset (data()[0], 0, sample_size(0).height * stride()[0]);
347 memset (data()[1], eight_bit_uv + 1, sample_size(1).height * stride()[1]);
348 memset (data()[2], eight_bit_uv + 1, sample_size(2).height * stride()[2]);
351 case AV_PIX_FMT_YUV422P9LE:
352 case AV_PIX_FMT_YUV444P9LE:
353 yuv_16_black (nine_bit_uv, false);
356 case AV_PIX_FMT_YUV422P9BE:
357 case AV_PIX_FMT_YUV444P9BE:
358 yuv_16_black (swap_16 (nine_bit_uv), false);
361 case AV_PIX_FMT_YUV422P10LE:
362 case AV_PIX_FMT_YUV444P10LE:
363 yuv_16_black (ten_bit_uv, false);
366 case AV_PIX_FMT_YUV422P16LE:
367 case AV_PIX_FMT_YUV444P16LE:
368 yuv_16_black (sixteen_bit_uv, false);
371 case AV_PIX_FMT_YUV444P10BE:
372 case AV_PIX_FMT_YUV422P10BE:
373 yuv_16_black (swap_16 (ten_bit_uv), false);
376 case AV_PIX_FMT_YUVA420P9BE:
377 case AV_PIX_FMT_YUVA422P9BE:
378 case AV_PIX_FMT_YUVA444P9BE:
379 yuv_16_black (swap_16 (nine_bit_uv), true);
382 case AV_PIX_FMT_YUVA420P9LE:
383 case AV_PIX_FMT_YUVA422P9LE:
384 case AV_PIX_FMT_YUVA444P9LE:
385 yuv_16_black (nine_bit_uv, true);
388 case AV_PIX_FMT_YUVA420P10BE:
389 case AV_PIX_FMT_YUVA422P10BE:
390 case AV_PIX_FMT_YUVA444P10BE:
391 yuv_16_black (swap_16 (ten_bit_uv), true);
394 case AV_PIX_FMT_YUVA420P10LE:
395 case AV_PIX_FMT_YUVA422P10LE:
396 case AV_PIX_FMT_YUVA444P10LE:
397 yuv_16_black (ten_bit_uv, true);
400 case AV_PIX_FMT_YUVA420P16BE:
401 case AV_PIX_FMT_YUVA422P16BE:
402 case AV_PIX_FMT_YUVA444P16BE:
403 yuv_16_black (swap_16 (sixteen_bit_uv), true);
406 case AV_PIX_FMT_YUVA420P16LE:
407 case AV_PIX_FMT_YUVA422P16LE:
408 case AV_PIX_FMT_YUVA444P16LE:
409 yuv_16_black (sixteen_bit_uv, true);
412 case AV_PIX_FMT_RGB24:
413 case AV_PIX_FMT_ARGB:
414 case AV_PIX_FMT_RGBA:
415 case AV_PIX_FMT_ABGR:
416 case AV_PIX_FMT_BGRA:
417 case AV_PIX_FMT_RGB555LE:
418 case AV_PIX_FMT_RGB48LE:
419 case AV_PIX_FMT_RGB48BE:
420 case AV_PIX_FMT_XYZ12LE:
421 memset (data()[0], 0, sample_size(0).height * stride()[0]);
424 case AV_PIX_FMT_UYVY422:
426 int const Y = sample_size(0).height;
427 int const X = line_size()[0];
428 uint8_t* p = data()[0];
429 for (int y = 0; y < Y; ++y) {
430 for (int x = 0; x < X / 4; ++x) {
431 *p++ = eight_bit_uv; // Cb
433 *p++ = eight_bit_uv; // Cr
441 throw PixelFormatError ("make_black()", _pixel_format);
446 Image::make_transparent ()
448 if (_pixel_format != AV_PIX_FMT_BGRA) {
449 throw PixelFormatError ("make_transparent()", _pixel_format);
452 memset (data()[0], 0, sample_size(0).height * stride()[0]);
456 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
458 /* We're blending BGRA images; first byte is blue, second byte is green, third byte red, fourth byte alpha */
459 DCPOMATIC_ASSERT (other->pixel_format() == AV_PIX_FMT_BGRA);
460 int const other_bpp = 4;
462 int start_tx = position.x;
466 start_ox = -start_tx;
470 int start_ty = position.y;
474 start_oy = -start_ty;
478 switch (_pixel_format) {
479 case AV_PIX_FMT_RGB24:
481 /* Going onto RGB24. First byte is red, second green, third blue */
482 int const this_bpp = 3;
483 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
484 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
485 uint8_t* op = other->data()[0] + oy * other->stride()[0];
486 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
487 float const alpha = float (op[3]) / 255;
488 tp[0] = op[2] * alpha + tp[0] * (1 - alpha);
489 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
490 tp[2] = op[0] * alpha + tp[2] * (1 - alpha);
498 case AV_PIX_FMT_BGRA:
500 int const this_bpp = 4;
501 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
502 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
503 uint8_t* op = other->data()[0] + oy * other->stride()[0];
504 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
505 float const alpha = float (op[3]) / 255;
506 tp[0] = op[0] * alpha + tp[0] * (1 - alpha);
507 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
508 tp[2] = op[2] * alpha + tp[2] * (1 - alpha);
509 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
517 case AV_PIX_FMT_RGBA:
519 int const this_bpp = 4;
520 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
521 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
522 uint8_t* op = other->data()[0] + oy * other->stride()[0];
523 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
524 float const alpha = float (op[3]) / 255;
525 tp[0] = op[2] * alpha + tp[0] * (1 - alpha);
526 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
527 tp[2] = op[0] * alpha + tp[2] * (1 - alpha);
528 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
536 case AV_PIX_FMT_RGB48LE:
538 int const this_bpp = 6;
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 /* Blend high bytes */
545 tp[1] = op[2] * alpha + tp[1] * (1 - alpha);
546 tp[3] = op[1] * alpha + tp[3] * (1 - alpha);
547 tp[5] = op[0] * alpha + tp[5] * (1 - alpha);
555 case AV_PIX_FMT_XYZ12LE:
557 dcp::ColourConversion conv = dcp::ColourConversion::srgb_to_xyz();
558 double fast_matrix[9];
559 dcp::combined_rgb_to_xyz (conv, fast_matrix);
560 double const * lut_in = conv.in()->lut (8, false);
561 double const * lut_out = conv.out()->lut (16, true);
562 int const this_bpp = 6;
563 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
564 uint16_t* tp = reinterpret_cast<uint16_t*> (data()[0] + ty * stride()[0] + start_tx * this_bpp);
565 uint8_t* op = other->data()[0] + oy * other->stride()[0];
566 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
567 float const alpha = float (op[3]) / 255;
569 /* Convert sRGB to XYZ; op is BGRA. First, input gamma LUT */
570 double const r = lut_in[op[2]];
571 double const g = lut_in[op[1]];
572 double const b = lut_in[op[0]];
574 /* RGB to XYZ, including Bradford transform and DCI companding */
575 double const x = max (0.0, min (65535.0, r * fast_matrix[0] + g * fast_matrix[1] + b * fast_matrix[2]));
576 double const y = max (0.0, min (65535.0, r * fast_matrix[3] + g * fast_matrix[4] + b * fast_matrix[5]));
577 double const z = max (0.0, min (65535.0, r * fast_matrix[6] + g * fast_matrix[7] + b * fast_matrix[8]));
579 /* Out gamma LUT and blend */
580 tp[0] = lrint(lut_out[lrint(x)] * 65535) * alpha + tp[0] * (1 - alpha);
581 tp[1] = lrint(lut_out[lrint(y)] * 65535) * alpha + tp[1] * (1 - alpha);
582 tp[2] = lrint(lut_out[lrint(z)] * 65535) * alpha + tp[2] * (1 - alpha);
590 case AV_PIX_FMT_YUV420P:
592 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
593 dcp::Size const ts = size();
594 dcp::Size const os = yuv->size();
595 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
596 int const hty = ty / 2;
597 int const hoy = oy / 2;
598 uint8_t* tY = data()[0] + (ty * stride()[0]) + start_tx;
599 uint8_t* tU = data()[1] + (hty * stride()[1]) + start_tx / 2;
600 uint8_t* tV = data()[2] + (hty * stride()[2]) + start_tx / 2;
601 uint8_t* oY = yuv->data()[0] + (oy * yuv->stride()[0]) + start_ox;
602 uint8_t* oU = yuv->data()[1] + (hoy * yuv->stride()[1]) + start_ox / 2;
603 uint8_t* oV = yuv->data()[2] + (hoy * yuv->stride()[2]) + start_ox / 2;
604 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
605 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
606 float const a = float(alpha[3]) / 255;
607 *tY = *oY * a + *tY * (1 - a);
608 *tU = *oU * a + *tU * (1 - a);
609 *tV = *oV * a + *tV * (1 - a);
625 case AV_PIX_FMT_YUV420P10:
627 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
628 dcp::Size const ts = size();
629 dcp::Size const os = yuv->size();
630 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
631 int const hty = ty / 2;
632 int const hoy = oy / 2;
633 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
634 uint16_t* tU = ((uint16_t *) (data()[1] + (hty * stride()[1]))) + start_tx / 2;
635 uint16_t* tV = ((uint16_t *) (data()[2] + (hty * stride()[2]))) + start_tx / 2;
636 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
637 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (hoy * yuv->stride()[1]))) + start_ox / 2;
638 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (hoy * yuv->stride()[2]))) + start_ox / 2;
639 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
640 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
641 float const a = float(alpha[3]) / 255;
642 *tY = *oY * a + *tY * (1 - a);
643 *tU = *oU * a + *tU * (1 - a);
644 *tV = *oV * a + *tV * (1 - a);
660 case AV_PIX_FMT_YUV422P10LE:
662 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
663 dcp::Size const ts = size();
664 dcp::Size const os = yuv->size();
665 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
666 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
667 uint16_t* tU = ((uint16_t *) (data()[1] + (ty * stride()[1]))) + start_tx / 2;
668 uint16_t* tV = ((uint16_t *) (data()[2] + (ty * stride()[2]))) + start_tx / 2;
669 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
670 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (oy * yuv->stride()[1]))) + start_ox / 2;
671 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (oy * yuv->stride()[2]))) + start_ox / 2;
672 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
673 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
674 float const a = float(alpha[3]) / 255;
675 *tY = *oY * a + *tY * (1 - a);
676 *tU = *oU * a + *tU * (1 - a);
677 *tV = *oV * a + *tV * (1 - a);
694 throw PixelFormatError ("alpha_blend()", _pixel_format);
699 Image::copy (shared_ptr<const Image> other, Position<int> position)
701 /* Only implemented for RGB24 onto RGB24 so far */
702 DCPOMATIC_ASSERT (_pixel_format == AV_PIX_FMT_RGB24 && other->pixel_format() == AV_PIX_FMT_RGB24);
703 DCPOMATIC_ASSERT (position.x >= 0 && position.y >= 0);
705 int const N = min (position.x + other->size().width, size().width) - position.x;
706 for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
707 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
708 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
709 memcpy (tp, op, N * 3);
714 Image::read_from_socket (shared_ptr<Socket> socket)
716 for (int i = 0; i < planes(); ++i) {
717 uint8_t* p = data()[i];
718 int const lines = sample_size(i).height;
719 for (int y = 0; y < lines; ++y) {
720 socket->read (p, line_size()[i]);
727 Image::write_to_socket (shared_ptr<Socket> socket) const
729 for (int i = 0; i < planes(); ++i) {
730 uint8_t* p = data()[i];
731 int const lines = sample_size(i).height;
732 for (int y = 0; y < lines; ++y) {
733 socket->write (p, line_size()[i]);
740 Image::bytes_per_pixel (int c) const
742 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
744 throw PixelFormatError ("bytes_per_pixel()", _pixel_format);
751 float bpp[4] = { 0, 0, 0, 0 };
753 #ifdef DCPOMATIC_HAVE_AVCOMPONENTDESCRIPTOR_DEPTH_MINUS1
754 bpp[0] = floor ((d->comp[0].depth_minus1 + 8) / 8);
755 if (d->nb_components > 1) {
756 bpp[1] = floor ((d->comp[1].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
758 if (d->nb_components > 2) {
759 bpp[2] = floor ((d->comp[2].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
761 if (d->nb_components > 3) {
762 bpp[3] = floor ((d->comp[3].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
765 bpp[0] = floor ((d->comp[0].depth + 7) / 8);
766 if (d->nb_components > 1) {
767 bpp[1] = floor ((d->comp[1].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
769 if (d->nb_components > 2) {
770 bpp[2] = floor ((d->comp[2].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
772 if (d->nb_components > 3) {
773 bpp[3] = floor ((d->comp[3].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
777 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
778 /* Not planar; sum them up */
779 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
785 /** Construct a Image of a given size and format, allocating memory
788 * @param p Pixel format.
789 * @param s Size in pixels.
790 * @param aligned true to make each row of this image aligned to a 32-byte boundary.
791 * @param extra_pixels Amount of extra "run-off" memory to allocate at the end of each plane in pixels.
793 Image::Image (AVPixelFormat p, dcp::Size s, bool aligned, int extra_pixels)
797 , _extra_pixels (extra_pixels)
805 _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
806 _data[0] = _data[1] = _data[2] = _data[3] = 0;
808 _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
809 _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
811 _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
812 _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
814 for (int i = 0; i < planes(); ++i) {
815 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
816 _stride[i] = stride_round_up (i, _line_size, _aligned ? 32 : 1);
818 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
819 uses a 16-byte fetch to read three bytes (R/G/B) of image data.
820 Hence on the last pixel of the last line it reads over the end of
821 the actual data by 1 byte. If the width of an image is a multiple
822 of the stride alignment there will be no padding at the end of image lines.
823 OS X crashes on this illegal read, though other operating systems don't
824 seem to mind. The nasty + 1 in this malloc makes sure there is always a byte
825 for that instruction to read safely.
827 Further to the above, valgrind is now telling me that ff_rgb24ToY_ssse3
828 over-reads by more then _avx. I can't follow the code to work out how much,
829 so I'll just over-allocate by 32 bytes and have done with it. Empirical
830 testing suggests that it works.
832 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * sample_size(i).height + _extra_pixels * bytes_per_pixel(i) + 32);
833 #if HAVE_VALGRIND_MEMCHECK_H
834 /* The data between the end of the line size and the stride is undefined but processed by
835 libswscale, causing lots of valgrind errors. Mark it all defined to quell these errors.
837 VALGRIND_MAKE_MEM_DEFINED (_data[i], _stride[i] * sample_size(i).height + _extra_pixels * bytes_per_pixel(i) + 32);
842 Image::Image (Image const & other)
843 : boost::enable_shared_from_this<Image>(other)
844 , _size (other._size)
845 , _pixel_format (other._pixel_format)
846 , _aligned (other._aligned)
847 , _extra_pixels (other._extra_pixels)
851 for (int i = 0; i < planes(); ++i) {
852 uint8_t* p = _data[i];
853 uint8_t* q = other._data[i];
854 int const lines = sample_size(i).height;
855 for (int j = 0; j < lines; ++j) {
856 memcpy (p, q, _line_size[i]);
858 q += other.stride()[i];
863 Image::Image (AVFrame* frame)
864 : _size (frame->width, frame->height)
865 , _pixel_format (static_cast<AVPixelFormat> (frame->format))
871 for (int i = 0; i < planes(); ++i) {
872 uint8_t* p = _data[i];
873 uint8_t* q = frame->data[i];
874 int const lines = sample_size(i).height;
875 for (int j = 0; j < lines; ++j) {
876 memcpy (p, q, _line_size[i]);
878 /* AVFrame's linesize is what we call `stride' */
879 q += frame->linesize[i];
884 Image::Image (shared_ptr<const Image> other, bool aligned)
885 : _size (other->_size)
886 , _pixel_format (other->_pixel_format)
888 , _extra_pixels (other->_extra_pixels)
892 for (int i = 0; i < planes(); ++i) {
893 DCPOMATIC_ASSERT (line_size()[i] == other->line_size()[i]);
894 uint8_t* p = _data[i];
895 uint8_t* q = other->data()[i];
896 int const lines = sample_size(i).height;
897 for (int j = 0; j < lines; ++j) {
898 memcpy (p, q, line_size()[i]);
900 q += other->stride()[i];
906 Image::operator= (Image const & other)
908 if (this == &other) {
918 Image::swap (Image & other)
920 std::swap (_size, other._size);
921 std::swap (_pixel_format, other._pixel_format);
923 for (int i = 0; i < 4; ++i) {
924 std::swap (_data[i], other._data[i]);
925 std::swap (_line_size[i], other._line_size[i]);
926 std::swap (_stride[i], other._stride[i]);
929 std::swap (_aligned, other._aligned);
930 std::swap (_extra_pixels, other._extra_pixels);
933 /** Destroy a Image */
936 for (int i = 0; i < planes(); ++i) {
941 av_free (_line_size);
952 Image::line_size () const
958 Image::stride () const
970 Image::aligned () const
976 merge (list<PositionImage> images)
978 if (images.empty ()) {
979 return PositionImage ();
982 if (images.size() == 1) {
983 return images.front ();
986 dcpomatic::Rect<int> all (images.front().position, images.front().image->size().width, images.front().image->size().height);
987 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
988 all.extend (dcpomatic::Rect<int> (i->position, i->image->size().width, i->image->size().height));
991 shared_ptr<Image> merged (new Image (images.front().image->pixel_format (), dcp::Size (all.width, all.height), true));
992 merged->make_transparent ();
993 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
994 merged->alpha_blend (i->image, i->position - all.position());
997 return PositionImage (merged, all.position ());
1001 operator== (Image const & a, Image const & b)
1003 if (a.planes() != b.planes() || a.pixel_format() != b.pixel_format() || a.aligned() != b.aligned()) {
1007 for (int c = 0; c < a.planes(); ++c) {
1008 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]) {
1012 uint8_t* p = a.data()[c];
1013 uint8_t* q = b.data()[c];
1014 int const lines = a.sample_size(c).height;
1015 for (int y = 0; y < lines; ++y) {
1016 if (memcmp (p, q, a.line_size()[c]) != 0) {
1029 * @param f Amount to fade by; 0 is black, 1 is no fade.
1032 Image::fade (float f)
1034 switch (_pixel_format) {
1035 case AV_PIX_FMT_YUV420P:
1036 case AV_PIX_FMT_YUV422P:
1037 case AV_PIX_FMT_YUV444P:
1038 case AV_PIX_FMT_YUV411P:
1039 case AV_PIX_FMT_YUVJ420P:
1040 case AV_PIX_FMT_YUVJ422P:
1041 case AV_PIX_FMT_YUVJ444P:
1042 case AV_PIX_FMT_RGB24:
1043 case AV_PIX_FMT_ARGB:
1044 case AV_PIX_FMT_RGBA:
1045 case AV_PIX_FMT_ABGR:
1046 case AV_PIX_FMT_BGRA:
1047 case AV_PIX_FMT_RGB555LE:
1049 for (int c = 0; c < 3; ++c) {
1050 uint8_t* p = data()[c];
1051 int const lines = sample_size(c).height;
1052 for (int y = 0; y < lines; ++y) {
1054 for (int x = 0; x < line_size()[c]; ++x) {
1055 *q = int (float (*q) * f);
1063 case AV_PIX_FMT_YUV422P9LE:
1064 case AV_PIX_FMT_YUV444P9LE:
1065 case AV_PIX_FMT_YUV422P10LE:
1066 case AV_PIX_FMT_YUV444P10LE:
1067 case AV_PIX_FMT_YUV422P16LE:
1068 case AV_PIX_FMT_YUV444P16LE:
1069 case AV_PIX_FMT_YUVA420P9LE:
1070 case AV_PIX_FMT_YUVA422P9LE:
1071 case AV_PIX_FMT_YUVA444P9LE:
1072 case AV_PIX_FMT_YUVA420P10LE:
1073 case AV_PIX_FMT_YUVA422P10LE:
1074 case AV_PIX_FMT_YUVA444P10LE:
1075 case AV_PIX_FMT_RGB48LE:
1076 case AV_PIX_FMT_XYZ12LE:
1077 /* 16-bit little-endian */
1078 for (int c = 0; c < 3; ++c) {
1079 int const stride_pixels = stride()[c] / 2;
1080 int const line_size_pixels = line_size()[c] / 2;
1081 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1082 int const lines = sample_size(c).height;
1083 for (int y = 0; y < lines; ++y) {
1085 for (int x = 0; x < line_size_pixels; ++x) {
1086 *q = int (float (*q) * f);
1094 case AV_PIX_FMT_YUV422P9BE:
1095 case AV_PIX_FMT_YUV444P9BE:
1096 case AV_PIX_FMT_YUV444P10BE:
1097 case AV_PIX_FMT_YUV422P10BE:
1098 case AV_PIX_FMT_YUVA420P9BE:
1099 case AV_PIX_FMT_YUVA422P9BE:
1100 case AV_PIX_FMT_YUVA444P9BE:
1101 case AV_PIX_FMT_YUVA420P10BE:
1102 case AV_PIX_FMT_YUVA422P10BE:
1103 case AV_PIX_FMT_YUVA444P10BE:
1104 case AV_PIX_FMT_YUVA420P16BE:
1105 case AV_PIX_FMT_YUVA422P16BE:
1106 case AV_PIX_FMT_YUVA444P16BE:
1107 case AV_PIX_FMT_RGB48BE:
1108 /* 16-bit big-endian */
1109 for (int c = 0; c < 3; ++c) {
1110 int const stride_pixels = stride()[c] / 2;
1111 int const line_size_pixels = line_size()[c] / 2;
1112 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1113 int const lines = sample_size(c).height;
1114 for (int y = 0; y < lines; ++y) {
1116 for (int x = 0; x < line_size_pixels; ++x) {
1117 *q = swap_16 (int (float (swap_16 (*q)) * f));
1125 case AV_PIX_FMT_UYVY422:
1127 int const Y = sample_size(0).height;
1128 int const X = line_size()[0];
1129 uint8_t* p = data()[0];
1130 for (int y = 0; y < Y; ++y) {
1131 for (int x = 0; x < X; ++x) {
1132 *p = int (float (*p) * f);
1140 throw PixelFormatError ("fade()", _pixel_format);
1144 shared_ptr<const Image>
1145 Image::ensure_aligned (shared_ptr<const Image> image)
1147 if (image->aligned()) {
1151 return shared_ptr<Image> (new Image (image, true));
1155 Image::memory_used () const
1158 for (int i = 0; i < planes(); ++i) {
1159 m += _stride[i] * sample_size(i).height;
1182 png_write_data (png_structp png_ptr, png_bytep data, png_size_t length)
1184 Memory* mem = reinterpret_cast<Memory*>(png_get_io_ptr(png_ptr));
1185 size_t size = mem->size + length;
1188 mem->data = reinterpret_cast<uint8_t*>(realloc(mem->data, size));
1190 mem->data = reinterpret_cast<uint8_t*>(malloc(size));
1194 throw EncodeError (N_("could not allocate memory for PNG"));
1197 memcpy (mem->data + mem->size, data, length);
1198 mem->size += length;
1202 png_flush (png_structp)
1208 png_error_fn (png_structp png_ptr, char const * message)
1210 reinterpret_cast<Image*>(png_get_error_ptr(png_ptr))->png_error (message);
1214 Image::png_error (char const * message)
1216 throw EncodeError (String::compose ("Error during PNG write: %1", message));
1220 Image::as_png () const
1222 DCPOMATIC_ASSERT (bytes_per_pixel(0) == 4);
1223 DCPOMATIC_ASSERT (planes() == 1);
1224 DCPOMATIC_ASSERT (pixel_format() == AV_PIX_FMT_BGRA);
1226 /* error handling? */
1227 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, reinterpret_cast<void*>(const_cast<Image*>(this)), png_error_fn, 0);
1229 throw EncodeError (N_("could not create PNG write struct"));
1234 png_set_write_fn (png_ptr, &state, png_write_data, png_flush);
1236 png_infop info_ptr = png_create_info_struct(png_ptr);
1238 png_destroy_write_struct (&png_ptr, &info_ptr);
1239 throw EncodeError (N_("could not create PNG info struct"));
1242 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);
1244 png_byte ** row_pointers = reinterpret_cast<png_byte **>(png_malloc(png_ptr, size().height * sizeof(png_byte *)));
1245 for (int i = 0; i < size().height; ++i) {
1246 row_pointers[i] = (png_byte *) (data()[0] + i * stride()[0]);
1249 png_write_info (png_ptr, info_ptr);
1250 png_write_image (png_ptr, row_pointers);
1251 png_write_end (png_ptr, info_ptr);
1253 png_destroy_write_struct (&png_ptr, &info_ptr);
1254 png_free (png_ptr, row_pointers);
1256 return dcp::Data (state.data, state.size);