Support alpha blend onto YUV444P9LE and YUV444P10LE (68 and 70).
[dcpomatic.git] / src / lib / image.cc
1 /*
2     Copyright (C) 2012-2021 Carl Hetherington <cth@carlh.net>
3
4     This file is part of DCP-o-matic.
5
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.
10
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.
15
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/>.
18
19 */
20
21
22 /** @file src/image.cc
23  *  @brief A class to describe a video image.
24  */
25
26
27 #include "compose.hpp"
28 #include "dcpomatic_assert.h"
29 #include "dcpomatic_socket.h"
30 #include "enum_indexed_vector.h"
31 #include "exceptions.h"
32 #include "image.h"
33 #include "maths_util.h"
34 #include "memory_util.h"
35 #include "rect.h"
36 #include "timer.h"
37 #include <dcp/rgb_xyz.h>
38 #include <dcp/transfer_function.h>
39 #include <dcp/warnings.h>
40 LIBDCP_DISABLE_WARNINGS
41 extern "C" {
42 #include <libavutil/frame.h>
43 #include <libavutil/pixdesc.h>
44 #include <libavutil/pixfmt.h>
45 #include <libswscale/swscale.h>
46 }
47 LIBDCP_ENABLE_WARNINGS
48 #if HAVE_VALGRIND_MEMCHECK_H
49 #include <valgrind/memcheck.h>
50 #endif
51 #include <iostream>
52
53
54 #include "i18n.h"
55
56
57 using std::cerr;
58 using std::cout;
59 using std::list;
60 using std::make_shared;
61 using std::max;
62 using std::min;
63 using std::runtime_error;
64 using std::shared_ptr;
65 using std::string;
66 using dcp::Size;
67
68
69 /** The memory alignment, in bytes, used for each row of an image if Alignment::PADDED is requested */
70 int constexpr ALIGNMENT = 64;
71
72 /* U/V black value for 8-bit colour */
73 static uint8_t const eight_bit_uv =     (1 << 7) - 1;
74 /* U/V black value for 9-bit colour */
75 static uint16_t const nine_bit_uv =     (1 << 8) - 1;
76 /* U/V black value for 10-bit colour */
77 static uint16_t const ten_bit_uv =      (1 << 9) - 1;
78 /* U/V black value for 16-bit colour */
79 static uint16_t const sixteen_bit_uv =  (1 << 15) - 1;
80
81
82 int
83 Image::vertical_factor (int n) const
84 {
85         if (n == 0) {
86                 return 1;
87         }
88
89         auto d = av_pix_fmt_desc_get(_pixel_format);
90         if (!d) {
91                 throw PixelFormatError ("line_factor()", _pixel_format);
92         }
93
94         return lrintf(powf(2.0f, d->log2_chroma_h));
95 }
96
97 int
98 Image::horizontal_factor (int n) const
99 {
100         if (n == 0) {
101                 return 1;
102         }
103
104         auto d = av_pix_fmt_desc_get(_pixel_format);
105         if (!d) {
106                 throw PixelFormatError ("sample_size()", _pixel_format);
107         }
108
109         return lrintf(powf(2.0f, d->log2_chroma_w));
110 }
111
112
113 /** @param n Component index.
114  *  @return Number of samples (i.e. pixels, unless sub-sampled) in each direction for this component.
115  */
116 dcp::Size
117 Image::sample_size (int n) const
118 {
119         return dcp::Size (
120                 lrint (ceil(static_cast<double>(size().width) / horizontal_factor(n))),
121                 lrint (ceil(static_cast<double>(size().height) / vertical_factor(n)))
122                 );
123 }
124
125
126 /** @return Number of planes */
127 int
128 Image::planes () const
129 {
130         if (_pixel_format == AV_PIX_FMT_PAL8) {
131                 return 2;
132         }
133
134         auto d = av_pix_fmt_desc_get(_pixel_format);
135         if (!d) {
136                 throw PixelFormatError ("planes()", _pixel_format);
137         }
138
139         if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
140                 return 1;
141         }
142
143         return d->nb_components;
144 }
145
146
147 static
148 int
149 round_width_for_subsampling (int p, AVPixFmtDescriptor const * desc)
150 {
151         return p & ~ ((1 << desc->log2_chroma_w) - 1);
152 }
153
154
155 static
156 int
157 round_height_for_subsampling (int p, AVPixFmtDescriptor const * desc)
158 {
159         return p & ~ ((1 << desc->log2_chroma_h) - 1);
160 }
161
162
163 /** Crop this image, scale it to `inter_size' and then place it in a black frame of `out_size'.
164  *  @param crop Amount to crop by.
165  *  @param inter_size Size to scale the cropped image to.
166  *  @param out_size Size of output frame; if this is larger than inter_size there will be black padding.
167  *  @param yuv_to_rgb YUV to RGB transformation to use, if required.
168  *  @param video_range Video range of the image.
169  *  @param out_format Output pixel format.
170  *  @param out_aligned true to make the output image aligned.
171  *  @param out_video_range Video range to use for the output image.
172  *  @param fast Try to be fast at the possible expense of quality; at present this means using
173  *  fast bilinear rather than bicubic scaling.
174  */
175 shared_ptr<Image>
176 Image::crop_scale_window (
177         Crop crop,
178         dcp::Size inter_size,
179         dcp::Size out_size,
180         dcp::YUVToRGB yuv_to_rgb,
181         VideoRange video_range,
182         AVPixelFormat out_format,
183         VideoRange out_video_range,
184         Alignment out_alignment,
185         bool fast
186         ) const
187 {
188         /* Empirical testing suggests that sws_scale() will crash if
189            the input image is not padded.
190         */
191         DCPOMATIC_ASSERT (alignment() == Alignment::PADDED);
192
193         DCPOMATIC_ASSERT (out_size.width >= inter_size.width);
194         DCPOMATIC_ASSERT (out_size.height >= inter_size.height);
195
196         auto out = make_shared<Image>(out_format, out_size, out_alignment);
197         out->make_black ();
198
199         auto in_desc = av_pix_fmt_desc_get (_pixel_format);
200         if (!in_desc) {
201                 throw PixelFormatError ("crop_scale_window()", _pixel_format);
202         }
203
204         /* Round down so that we crop only the number of pixels that is straightforward
205          * considering any subsampling.
206          */
207         Crop corrected_crop(
208                 round_width_for_subsampling(crop.left, in_desc),
209                 round_width_for_subsampling(crop.right, in_desc),
210                 round_height_for_subsampling(crop.top, in_desc),
211                 round_height_for_subsampling(crop.bottom, in_desc)
212                 );
213
214         /* Also check that we aren't cropping more image than there actually is */
215         if ((corrected_crop.left + corrected_crop.right) >= (size().width - 4)) {
216                 corrected_crop.left = 0;
217                 corrected_crop.right = size().width - 4;
218         }
219
220         if ((corrected_crop.top + corrected_crop.bottom) >= (size().height - 4)) {
221                 corrected_crop.top = 0;
222                 corrected_crop.bottom = size().height - 4;
223         }
224
225         /* Size of the image after any crop */
226         auto const cropped_size = corrected_crop.apply (size());
227
228         /* Scale context for a scale from cropped_size to inter_size */
229         auto scale_context = sws_getContext (
230                         cropped_size.width, cropped_size.height, pixel_format(),
231                         inter_size.width, inter_size.height, out_format,
232                         fast ? SWS_FAST_BILINEAR : SWS_BICUBIC, 0, 0, 0
233                 );
234
235         if (!scale_context) {
236                 throw runtime_error (N_("Could not allocate SwsContext"));
237         }
238
239         DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUVToRGB::COUNT);
240         EnumIndexedVector<int, dcp::YUVToRGB> lut;
241         lut[dcp::YUVToRGB::REC601] = SWS_CS_ITU601;
242         lut[dcp::YUVToRGB::REC709] = SWS_CS_ITU709;
243         lut[dcp::YUVToRGB::REC2020] = SWS_CS_BT2020;
244
245         /* The 3rd parameter here is:
246            0 -> source range MPEG (i.e. "video", 16-235)
247            1 -> source range JPEG (i.e. "full", 0-255)
248            And the 5th:
249            0 -> destination range MPEG (i.e. "video", 16-235)
250            1 -> destination range JPEG (i.e. "full", 0-255)
251
252            But remember: sws_setColorspaceDetails ignores these
253            parameters unless the both source and destination images
254            are isYUV or isGray.  (If either is not, it uses video range).
255         */
256         sws_setColorspaceDetails (
257                 scale_context,
258                 sws_getCoefficients(lut[yuv_to_rgb]), video_range == VideoRange::VIDEO ? 0 : 1,
259                 sws_getCoefficients(lut[yuv_to_rgb]), out_video_range == VideoRange::VIDEO ? 0 : 1,
260                 0, 1 << 16, 1 << 16
261                 );
262
263         /* Prepare input data pointers with crop */
264         uint8_t* scale_in_data[planes()];
265         for (int c = 0; c < planes(); ++c) {
266                 int const x = lrintf(bytes_per_pixel(c) * corrected_crop.left);
267                 scale_in_data[c] = data()[c] + x + stride()[c] * (corrected_crop.top / vertical_factor(c));
268         }
269
270         auto out_desc = av_pix_fmt_desc_get (out_format);
271         if (!out_desc) {
272                 throw PixelFormatError ("crop_scale_window()", out_format);
273         }
274
275         /* Corner of the image within out_size */
276         Position<int> const corner (
277                 round_width_for_subsampling((out_size.width - inter_size.width) / 2, out_desc),
278                 round_height_for_subsampling((out_size.height - inter_size.height) / 2, out_desc)
279                 );
280
281         uint8_t* scale_out_data[out->planes()];
282         for (int c = 0; c < out->planes(); ++c) {
283                 int const x = lrintf(out->bytes_per_pixel(c) * corner.x);
284                 scale_out_data[c] = out->data()[c] + x + out->stride()[c] * (corner.y / out->vertical_factor(c));
285         }
286
287         sws_scale (
288                 scale_context,
289                 scale_in_data, stride(),
290                 0, cropped_size.height,
291                 scale_out_data, out->stride()
292                 );
293
294         sws_freeContext (scale_context);
295
296         /* There are some cases where there will be unwanted image data left in the image at this point:
297          *
298          * 1. When we are cropping without any scaling or pixel format conversion.
299          * 2. When we are scaling to certain sizes and placing the result into a larger
300          *    black frame.
301          *
302          * Clear out the sides of the image to take care of those cases.
303          */
304         auto const pad = (out_size.width - inter_size.width) / 2;
305         out->make_part_black(0, pad);
306         out->make_part_black(corner.x + inter_size.width, pad);
307
308         if (
309                 video_range == VideoRange::VIDEO &&
310                 out_video_range == VideoRange::FULL &&
311                 av_pix_fmt_desc_get(_pixel_format)->flags & AV_PIX_FMT_FLAG_RGB
312            ) {
313                 /* libswscale will not convert video range for RGB sources, so we have to do it ourselves */
314                 out->video_range_to_full_range ();
315         }
316
317         return out;
318 }
319
320
321 shared_ptr<Image>
322 Image::convert_pixel_format (dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, Alignment out_alignment, bool fast) const
323 {
324         return scale(size(), yuv_to_rgb, out_format, out_alignment, fast);
325 }
326
327
328 /** @param out_size Size to scale to.
329  *  @param yuv_to_rgb YUVToRGB transform transform to use, if required.
330  *  @param out_format Output pixel format.
331  *  @param out_alignment Output alignment.
332  *  @param fast Try to be fast at the possible expense of quality; at present this means using
333  *  fast bilinear rather than bicubic scaling.
334  */
335 shared_ptr<Image>
336 Image::scale (dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, Alignment out_alignment, bool fast) const
337 {
338         /* Empirical testing suggests that sws_scale() will crash if
339            the input image alignment is not PADDED.
340         */
341         DCPOMATIC_ASSERT (alignment() == Alignment::PADDED);
342
343         auto scaled = make_shared<Image>(out_format, out_size, out_alignment);
344         auto scale_context = sws_getContext (
345                 size().width, size().height, pixel_format(),
346                 out_size.width, out_size.height, out_format,
347                 (fast ? SWS_FAST_BILINEAR : SWS_BICUBIC) | SWS_ACCURATE_RND, 0, 0, 0
348                 );
349
350         DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUVToRGB::COUNT);
351         EnumIndexedVector<int, dcp::YUVToRGB> lut;
352         lut[dcp::YUVToRGB::REC601] = SWS_CS_ITU601;
353         lut[dcp::YUVToRGB::REC709] = SWS_CS_ITU709;
354         lut[dcp::YUVToRGB::REC2020] = SWS_CS_BT2020;
355
356         /* The 3rd parameter here is:
357            0 -> source range MPEG (i.e. "video", 16-235)
358            1 -> source range JPEG (i.e. "full", 0-255)
359            And the 5th:
360            0 -> destination range MPEG (i.e. "video", 16-235)
361            1 -> destination range JPEG (i.e. "full", 0-255)
362
363            But remember: sws_setColorspaceDetails ignores these
364            parameters unless the corresponding image isYUV or isGray.
365            (If it's neither, it uses video range).
366         */
367         sws_setColorspaceDetails (
368                 scale_context,
369                 sws_getCoefficients(lut[yuv_to_rgb]), 0,
370                 sws_getCoefficients(lut[yuv_to_rgb]), 0,
371                 0, 1 << 16, 1 << 16
372                 );
373
374         sws_scale (
375                 scale_context,
376                 data(), stride(),
377                 0, size().height,
378                 scaled->data(), scaled->stride()
379                 );
380
381         sws_freeContext (scale_context);
382
383         return scaled;
384 }
385
386
387 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
388 void
389 Image::yuv_16_black (uint16_t v, bool alpha)
390 {
391         memset (data()[0], 0, sample_size(0).height * stride()[0]);
392         for (int i = 1; i < 3; ++i) {
393                 auto p = reinterpret_cast<int16_t*> (data()[i]);
394                 int const lines = sample_size(i).height;
395                 for (int y = 0; y < lines; ++y) {
396                         /* We divide by 2 here because we are writing 2 bytes at a time */
397                         for (int x = 0; x < line_size()[i] / 2; ++x) {
398                                 p[x] = v;
399                         }
400                         p += stride()[i] / 2;
401                 }
402         }
403
404         if (alpha) {
405                 memset (data()[3], 0, sample_size(3).height * stride()[3]);
406         }
407 }
408
409
410 uint16_t
411 Image::swap_16 (uint16_t v)
412 {
413         return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
414 }
415
416
417 void
418 Image::make_part_black (int const start, int const width)
419 {
420         auto y_part = [&]() {
421                 int const bpp = bytes_per_pixel(0);
422                 int const h = sample_size(0).height;
423                 int const s = stride()[0];
424                 auto p = data()[0];
425                 for (int y = 0; y < h; ++y) {
426                         memset (p + start * bpp, 0, width * bpp);
427                         p += s;
428                 }
429         };
430
431         switch (_pixel_format) {
432         case AV_PIX_FMT_RGB24:
433         case AV_PIX_FMT_ARGB:
434         case AV_PIX_FMT_RGBA:
435         case AV_PIX_FMT_ABGR:
436         case AV_PIX_FMT_BGRA:
437         case AV_PIX_FMT_RGB555LE:
438         case AV_PIX_FMT_RGB48LE:
439         case AV_PIX_FMT_RGB48BE:
440         case AV_PIX_FMT_XYZ12LE:
441         {
442                 int const h = sample_size(0).height;
443                 int const bpp = bytes_per_pixel(0);
444                 int const s = stride()[0];
445                 uint8_t* p = data()[0];
446                 for (int y = 0; y < h; y++) {
447                         memset (p + start * bpp, 0, width * bpp);
448                         p += s;
449                 }
450                 break;
451         }
452         case AV_PIX_FMT_YUV420P:
453         {
454                 y_part ();
455                 for (int i = 1; i < 3; ++i) {
456                         auto p = data()[i];
457                         int const h = sample_size(i).height;
458                         for (int y = 0; y < h; ++y) {
459                                 for (int x = start / 2; x < (start + width) / 2; ++x) {
460                                         p[x] = eight_bit_uv;
461                                 }
462                                 p += stride()[i];
463                         }
464                 }
465                 break;
466         }
467         case AV_PIX_FMT_YUV422P10LE:
468         {
469                 y_part ();
470                 for (int i = 1; i < 3; ++i) {
471                         auto p = reinterpret_cast<int16_t*>(data()[i]);
472                         int const h = sample_size(i).height;
473                         for (int y = 0; y < h; ++y) {
474                                 for (int x = start / 2; x < (start + width) / 2; ++x) {
475                                         p[x] = ten_bit_uv;
476                                 }
477                                 p += stride()[i] / 2;
478                         }
479                 }
480                 break;
481         }
482         case AV_PIX_FMT_YUV444P10LE:
483         {
484                 y_part();
485                 for (int i = 1; i < 3; ++i) {
486                         auto p = reinterpret_cast<int16_t*>(data()[i]);
487                         int const h = sample_size(i).height;
488                         for (int y = 0; y < h; ++y) {
489                                 for (int x = start; x < (start + width); ++x) {
490                                         p[x] = ten_bit_uv;
491                                 }
492                                 p += stride()[i] / 2;
493                         }
494                 }
495                 break;
496         }
497         default:
498                 throw PixelFormatError ("make_part_black()", _pixel_format);
499         }
500 }
501
502
503 void
504 Image::make_black ()
505 {
506         switch (_pixel_format) {
507         case AV_PIX_FMT_YUV420P:
508         case AV_PIX_FMT_YUV422P:
509         case AV_PIX_FMT_YUV444P:
510         case AV_PIX_FMT_YUV411P:
511                 memset (data()[0], 0, sample_size(0).height * stride()[0]);
512                 memset (data()[1], eight_bit_uv, sample_size(1).height * stride()[1]);
513                 memset (data()[2], eight_bit_uv, sample_size(2).height * stride()[2]);
514                 break;
515
516         case AV_PIX_FMT_YUVJ420P:
517         case AV_PIX_FMT_YUVJ422P:
518         case AV_PIX_FMT_YUVJ444P:
519                 memset (data()[0], 0, sample_size(0).height * stride()[0]);
520                 memset (data()[1], eight_bit_uv + 1, sample_size(1).height * stride()[1]);
521                 memset (data()[2], eight_bit_uv + 1, sample_size(2).height * stride()[2]);
522                 break;
523
524         case AV_PIX_FMT_YUV422P9LE:
525         case AV_PIX_FMT_YUV444P9LE:
526                 yuv_16_black (nine_bit_uv, false);
527                 break;
528
529         case AV_PIX_FMT_YUV422P9BE:
530         case AV_PIX_FMT_YUV444P9BE:
531                 yuv_16_black (swap_16 (nine_bit_uv), false);
532                 break;
533
534         case AV_PIX_FMT_YUV422P10LE:
535         case AV_PIX_FMT_YUV444P10LE:
536                 yuv_16_black (ten_bit_uv, false);
537                 break;
538
539         case AV_PIX_FMT_YUV422P16LE:
540         case AV_PIX_FMT_YUV444P16LE:
541                 yuv_16_black (sixteen_bit_uv, false);
542                 break;
543
544         case AV_PIX_FMT_YUV444P10BE:
545         case AV_PIX_FMT_YUV422P10BE:
546                 yuv_16_black (swap_16 (ten_bit_uv), false);
547                 break;
548
549         case AV_PIX_FMT_YUVA420P9BE:
550         case AV_PIX_FMT_YUVA422P9BE:
551         case AV_PIX_FMT_YUVA444P9BE:
552                 yuv_16_black (swap_16 (nine_bit_uv), true);
553                 break;
554
555         case AV_PIX_FMT_YUVA420P9LE:
556         case AV_PIX_FMT_YUVA422P9LE:
557         case AV_PIX_FMT_YUVA444P9LE:
558                 yuv_16_black (nine_bit_uv, true);
559                 break;
560
561         case AV_PIX_FMT_YUVA420P10BE:
562         case AV_PIX_FMT_YUVA422P10BE:
563         case AV_PIX_FMT_YUVA444P10BE:
564                 yuv_16_black (swap_16 (ten_bit_uv), true);
565                 break;
566
567         case AV_PIX_FMT_YUVA420P10LE:
568         case AV_PIX_FMT_YUVA422P10LE:
569         case AV_PIX_FMT_YUVA444P10LE:
570                 yuv_16_black (ten_bit_uv, true);
571                 break;
572
573         case AV_PIX_FMT_YUVA420P16BE:
574         case AV_PIX_FMT_YUVA422P16BE:
575         case AV_PIX_FMT_YUVA444P16BE:
576                 yuv_16_black (swap_16 (sixteen_bit_uv), true);
577                 break;
578
579         case AV_PIX_FMT_YUVA420P16LE:
580         case AV_PIX_FMT_YUVA422P16LE:
581         case AV_PIX_FMT_YUVA444P16LE:
582                 yuv_16_black (sixteen_bit_uv, true);
583                 break;
584
585         case AV_PIX_FMT_RGB24:
586         case AV_PIX_FMT_ARGB:
587         case AV_PIX_FMT_RGBA:
588         case AV_PIX_FMT_ABGR:
589         case AV_PIX_FMT_BGRA:
590         case AV_PIX_FMT_RGB555LE:
591         case AV_PIX_FMT_RGB48LE:
592         case AV_PIX_FMT_RGB48BE:
593         case AV_PIX_FMT_XYZ12LE:
594                 memset (data()[0], 0, sample_size(0).height * stride()[0]);
595                 break;
596
597         case AV_PIX_FMT_UYVY422:
598         {
599                 int const Y = sample_size(0).height;
600                 int const X = line_size()[0];
601                 uint8_t* p = data()[0];
602                 for (int y = 0; y < Y; ++y) {
603                         for (int x = 0; x < X / 4; ++x) {
604                                 *p++ = eight_bit_uv; // Cb
605                                 *p++ = 0;            // Y0
606                                 *p++ = eight_bit_uv; // Cr
607                                 *p++ = 0;            // Y1
608                         }
609                 }
610                 break;
611         }
612
613         default:
614                 throw PixelFormatError ("make_black()", _pixel_format);
615         }
616 }
617
618
619 void
620 Image::make_transparent ()
621 {
622         if (_pixel_format != AV_PIX_FMT_BGRA && _pixel_format != AV_PIX_FMT_RGBA && _pixel_format != AV_PIX_FMT_RGBA64BE) {
623                 throw PixelFormatError ("make_transparent()", _pixel_format);
624         }
625
626         memset (data()[0], 0, sample_size(0).height * stride()[0]);
627 }
628
629
630 struct TargetParams
631 {
632         int start_x;
633         int start_y;
634         dcp::Size size;
635         uint8_t* const* data;
636         int const* stride;
637         int bpp;
638
639         uint8_t* line_pointer(int y) const {
640                 return data[0] + y * stride[0] + start_x * bpp;
641         }
642 };
643
644
645 /** Parameters of the other image (the one being blended onto the target) when target and other are RGB */
646 struct OtherRGBParams
647 {
648         int start_x;
649         int start_y;
650         dcp::Size size;
651         uint8_t* const* data;
652         int const* stride;
653         int bpp;
654
655         uint8_t* line_pointer(int y) const {
656                 return data[0] + y * stride[0];
657         }
658
659         float alpha_divisor() const {
660                 return pow(2, bpp * 2) - 1;
661         }
662 };
663
664
665 /** Parameters of the other image (the one being blended onto the target) when target and other are YUV */
666 struct OtherYUVParams
667 {
668         int start_x;
669         int start_y;
670         dcp::Size size;
671         uint8_t* const* data;
672         int const* stride;
673
674         uint8_t* const* alpha_data;
675         int const* alpha_stride;
676         int alpha_bpp;
677 };
678
679
680 template <class OtherType>
681 void
682 alpha_blend_onto_rgb24(TargetParams const& target, OtherRGBParams const& other, int red, int blue, std::function<float (OtherType*)> get, int value_divisor)
683 {
684         /* Going onto RGB24.  First byte is red, second green, third blue */
685         auto const alpha_divisor = other.alpha_divisor();
686         for (int ty = target.start_y, oy = other.start_y; ty < target.size.height && oy < other.size.height; ++ty, ++oy) {
687                 auto tp = target.line_pointer(ty);
688                 auto op = reinterpret_cast<OtherType*>(other.line_pointer(oy));
689                 for (int tx = target.start_x, ox = other.start_x; tx < target.size.width && ox < other.size.width; ++tx, ++ox) {
690                         float const alpha = get(op + 3) / alpha_divisor;
691                         tp[0] = (get(op + red) / value_divisor) * alpha + tp[0] * (1 - alpha);
692                         tp[1] = (get(op + 1) / value_divisor) * alpha + tp[1] * (1 - alpha);
693                         tp[2] = (get(op + blue) / value_divisor) * alpha + tp[2] * (1 - alpha);
694
695                         tp += target.bpp;
696                         op += other.bpp / sizeof(OtherType);
697                 }
698         }
699 }
700
701
702 template <class OtherType>
703 void
704 alpha_blend_onto_bgra(TargetParams const& target, OtherRGBParams const& other, int red, int blue, std::function<float (OtherType*)> get, int value_divisor)
705 {
706         auto const alpha_divisor = other.alpha_divisor();
707         for (int ty = target.start_y, oy = other.start_y; ty < target.size.height && oy < other.size.height; ++ty, ++oy) {
708                 auto tp = target.line_pointer(ty);
709                 auto op = reinterpret_cast<OtherType*>(other.line_pointer(oy));
710                 for (int tx = target.start_x, ox = other.start_x; tx < target.size.width && ox < other.size.width; ++tx, ++ox) {
711                         float const alpha = get(op + 3) / alpha_divisor;
712                         tp[0] = (get(op + blue) / value_divisor) * alpha + tp[0] * (1 - alpha);
713                         tp[1] = (get(op + 1) / value_divisor) * alpha + tp[1] * (1 - alpha);
714                         tp[2] = (get(op + red) / value_divisor) * alpha + tp[2] * (1 - alpha);
715                         tp[3] = (get(op + 3) / value_divisor) * alpha + tp[3] * (1 - alpha);
716
717                         tp += target.bpp;
718                         op += other.bpp / sizeof(OtherType);
719                 }
720         }
721 }
722
723
724 template <class OtherType>
725 void
726 alpha_blend_onto_rgba(TargetParams const& target, OtherRGBParams const& other, int red, int blue, std::function<float (OtherType*)> get, int value_divisor)
727 {
728         auto const alpha_divisor = other.alpha_divisor();
729         for (int ty = target.start_y, oy = other.start_y; ty < target.size.height && oy < other.size.height; ++ty, ++oy) {
730                 auto tp = target.line_pointer(ty);
731                 auto op = reinterpret_cast<OtherType*>(other.line_pointer(oy));
732                 for (int tx = target.start_x, ox = other.start_x; tx < target.size.width && ox < other.size.width; ++tx, ++ox) {
733                         float const alpha = get(op + 3) / alpha_divisor;
734                         tp[0] = (get(op + red) / value_divisor) * alpha + tp[0] * (1 - alpha);
735                         tp[1] = (get(op + 1) / value_divisor) * alpha + tp[1] * (1 - alpha);
736                         tp[2] = (get(op + blue) / value_divisor) * alpha + tp[2] * (1 - alpha);
737                         tp[3] = (get(op + 3) / value_divisor) * alpha + tp[3] * (1 - alpha);
738
739                         tp += target.bpp;
740                         op += other.bpp / sizeof(OtherType);
741                 }
742         }
743 }
744
745
746 template <class OtherType>
747 void
748 alpha_blend_onto_rgb48le(TargetParams const& target, OtherRGBParams const& other, int red, int blue, std::function<float (OtherType*)> get, int value_scale)
749 {
750         auto const alpha_divisor = other.alpha_divisor();
751         for (int ty = target.start_y, oy = other.start_y; ty < target.size.height && oy < other.size.height; ++ty, ++oy) {
752                 auto tp = reinterpret_cast<uint16_t*>(target.line_pointer(ty));
753                 auto op = reinterpret_cast<OtherType*>(other.line_pointer(oy));
754                 for (int tx = target.start_x, ox = other.start_x; tx < target.size.width && ox < other.size.width; ++tx, ++ox) {
755                         float const alpha = get(op + 3) / alpha_divisor;
756                         tp[0] = get(op + red) * value_scale * alpha + tp[0] * (1 - alpha);
757                         tp[1] = get(op + 1) * value_scale * alpha + tp[1] * (1 - alpha);
758                         tp[2] = get(op + blue) * value_scale * alpha + tp[2] * (1 - alpha);
759
760                         tp += target.bpp / 2;
761                         op += other.bpp / sizeof(OtherType);
762                 }
763         }
764 }
765
766
767 template <class OtherType>
768 void
769 alpha_blend_onto_xyz12le(TargetParams const& target, OtherRGBParams const& other, int red, int blue, std::function<float (OtherType*)> get, int value_divisor)
770 {
771         auto const alpha_divisor = other.alpha_divisor();
772         auto conv = dcp::ColourConversion::srgb_to_xyz();
773         double fast_matrix[9];
774         dcp::combined_rgb_to_xyz(conv, fast_matrix);
775         auto lut_in = conv.in()->double_lut(0, 1, 8, false);
776         auto lut_out = conv.out()->int_lut(0, 1, 16, true, 65535);
777         for (int ty = target.start_y, oy = other.start_y; ty < target.size.height && oy < other.size.height; ++ty, ++oy) {
778                 auto tp = reinterpret_cast<uint16_t*>(target.data[0] + ty * target.stride[0] + target.start_x * target.bpp);
779                 auto op = reinterpret_cast<OtherType*>(other.data[0] + oy * other.stride[0]);
780                 for (int tx = target.start_x, ox = other.start_x; tx < target.size.width && ox < other.size.width; ++tx, ++ox) {
781                         float const alpha = get(op + 3) / alpha_divisor;
782
783                         /* Convert sRGB to XYZ; op is BGRA.  First, input gamma LUT */
784                         double const r = lut_in[get(op + red) / value_divisor];
785                         double const g = lut_in[get(op + 1) / value_divisor];
786                         double const b = lut_in[get(op + blue) / value_divisor];
787
788                         /* RGB to XYZ, including Bradford transform and DCI companding */
789                         double const x = max(0.0, min(1.0, r * fast_matrix[0] + g * fast_matrix[1] + b * fast_matrix[2]));
790                         double const y = max(0.0, min(1.0, r * fast_matrix[3] + g * fast_matrix[4] + b * fast_matrix[5]));
791                         double const z = max(0.0, min(1.0, r * fast_matrix[6] + g * fast_matrix[7] + b * fast_matrix[8]));
792
793                         /* Out gamma LUT and blend */
794                         tp[0] = lut_out[lrint(x * 65535)] * alpha + tp[0] * (1 - alpha);
795                         tp[1] = lut_out[lrint(y * 65535)] * alpha + tp[1] * (1 - alpha);
796                         tp[2] = lut_out[lrint(z * 65535)] * alpha + tp[2] * (1 - alpha);
797
798                         tp += target.bpp / 2;
799                         op += other.bpp / sizeof(OtherType);
800                 }
801         }
802 }
803
804
805 static
806 void
807 alpha_blend_onto_yuv420p(TargetParams const& target, OtherYUVParams const& other, std::function<float (uint8_t* data)> get_alpha)
808 {
809         auto const ts = target.size;
810         auto const os = other.size;
811         for (int ty = target.start_y, oy = other.start_y; ty < ts.height && oy < os.height; ++ty, ++oy) {
812                 int const hty = ty / 2;
813                 int const hoy = oy / 2;
814                 uint8_t* tY = target.data[0] + (ty * target.stride[0]) + target.start_x;
815                 uint8_t* tU = target.data[1] + (hty * target.stride[1]) + target.start_x / 2;
816                 uint8_t* tV = target.data[2] + (hty * target.stride[2]) + target.start_x / 2;
817                 uint8_t* oY = other.data[0] + (oy * other.stride[0]) + other.start_x;
818                 uint8_t* oU = other.data[1] + (hoy * other.stride[1]) + other.start_x / 2;
819                 uint8_t* oV = other.data[2] + (hoy * other.stride[2]) + other.start_x / 2;
820                 uint8_t* alpha = other.alpha_data[0] + (oy * other.alpha_stride[0]) + other.start_x * other.alpha_bpp;
821                 for (int tx = target.start_x, ox = other.start_x; tx < ts.width && ox < os.width; ++tx, ++ox) {
822                         float const a = get_alpha(alpha);
823                         *tY = *oY * a + *tY * (1 - a);
824                         *tU = *oU * a + *tU * (1 - a);
825                         *tV = *oV * a + *tV * (1 - a);
826                         ++tY;
827                         ++oY;
828                         if (tx % 2) {
829                                 ++tU;
830                                 ++tV;
831                         }
832                         if (ox % 2) {
833                                 ++oU;
834                                 ++oV;
835                         }
836                         alpha += other.alpha_bpp;
837                 }
838         }
839 }
840
841
842 static
843 void
844 alpha_blend_onto_yuv420p10(TargetParams const& target, OtherYUVParams const& other, std::function<float (uint8_t* data)> get_alpha)
845 {
846         auto const ts = target.size;
847         auto const os = other.size;
848         for (int ty = target.start_y, oy = other.start_y; ty < ts.height && oy < os.height; ++ty, ++oy) {
849                 int const hty = ty / 2;
850                 int const hoy = oy / 2;
851                 uint16_t* tY = reinterpret_cast<uint16_t*>(target.data[0] + (ty * target.stride[0])) + target.start_x;
852                 uint16_t* tU = reinterpret_cast<uint16_t*>(target.data[1] + (hty * target.stride[1])) + target.start_x / 2;
853                 uint16_t* tV = reinterpret_cast<uint16_t*>(target.data[2] + (hty * target.stride[2])) + target.start_x / 2;
854                 uint16_t* oY = reinterpret_cast<uint16_t*>(other.data[0] + (oy * other.stride[0])) + other.start_x;
855                 uint16_t* oU = reinterpret_cast<uint16_t*>(other.data[1] + (hoy * other.stride[1])) + other.start_x / 2;
856                 uint16_t* oV = reinterpret_cast<uint16_t*>(other.data[2] + (hoy * other.stride[2])) + other.start_x / 2;
857                 uint8_t* alpha = other.alpha_data[0] + (oy * other.alpha_stride[0]) + other.start_x * other.alpha_bpp;
858                 for (int tx = target.start_x, ox = other.start_x; tx < ts.width && ox < os.width; ++tx, ++ox) {
859                         float const a = get_alpha(alpha);
860                         *tY = *oY * a + *tY * (1 - a);
861                         *tU = *oU * a + *tU * (1 - a);
862                         *tV = *oV * a + *tV * (1 - a);
863                         ++tY;
864                         ++oY;
865                         if (tx % 2) {
866                                 ++tU;
867                                 ++tV;
868                         }
869                         if (ox % 2) {
870                                 ++oU;
871                                 ++oV;
872                         }
873                         alpha += other.alpha_bpp;
874                 }
875         }
876 }
877
878
879 static
880 void
881 alpha_blend_onto_yuv422p9or10le(TargetParams const& target, OtherYUVParams const& other, std::function<float (uint8_t* data)> get_alpha)
882 {
883         auto const ts = target.size;
884         auto const os = other.size;
885         for (int ty = target.start_y, oy = other.start_y; ty < ts.height && oy < os.height; ++ty, ++oy) {
886                 uint16_t* tY = reinterpret_cast<uint16_t*>(target.data[0] + (ty * target.stride[0])) + target.start_x;
887                 uint16_t* tU = reinterpret_cast<uint16_t*>(target.data[1] + (ty * target.stride[1])) + target.start_x / 2;
888                 uint16_t* tV = reinterpret_cast<uint16_t*>(target.data[2] + (ty * target.stride[2])) + target.start_x / 2;
889                 uint16_t* oY = reinterpret_cast<uint16_t*>(other.data[0] + (oy * other.stride[0])) + other.start_x;
890                 uint16_t* oU = reinterpret_cast<uint16_t*>(other.data[1] + (oy * other.stride[1])) + other.start_x / 2;
891                 uint16_t* oV = reinterpret_cast<uint16_t*>(other.data[2] + (oy * other.stride[2])) + other.start_x / 2;
892                 uint8_t* alpha = other.alpha_data[0] + (oy * other.alpha_stride[0]) + other.start_x * other.alpha_bpp;
893                 for (int tx = target.start_x, ox = other.start_x; tx < ts.width && ox < os.width; ++tx, ++ox) {
894                         float const a = get_alpha(alpha);
895                         *tY = *oY * a + *tY * (1 - a);
896                         *tU = *oU * a + *tU * (1 - a);
897                         *tV = *oV * a + *tV * (1 - a);
898                         ++tY;
899                         ++oY;
900                         if (tx % 2) {
901                                 ++tU;
902                                 ++tV;
903                         }
904                         if (ox % 2) {
905                                 ++oU;
906                                 ++oV;
907                         }
908                         alpha += other.alpha_bpp;
909                 }
910         }
911 }
912
913
914 static
915 void
916 alpha_blend_onto_yuv444p9or10le(TargetParams const& target, OtherYUVParams const& other, std::function<float (uint8_t* data)> get_alpha)
917 {
918         auto const ts = target.size;
919         auto const os = other.size;
920         for (int ty = target.start_y, oy = other.start_y; ty < ts.height && oy < os.height; ++ty, ++oy) {
921                 uint16_t* tY = reinterpret_cast<uint16_t*>(target.data[0] + (ty * target.stride[0])) + target.start_x;
922                 uint16_t* tU = reinterpret_cast<uint16_t*>(target.data[1] + (ty * target.stride[1])) + target.start_x;
923                 uint16_t* tV = reinterpret_cast<uint16_t*>(target.data[2] + (ty * target.stride[2])) + target.start_x;
924                 uint16_t* oY = reinterpret_cast<uint16_t*>(other.data[0] + (oy * other.stride[0])) + other.start_x;
925                 uint16_t* oU = reinterpret_cast<uint16_t*>(other.data[1] + (oy * other.stride[1])) + other.start_x;
926                 uint16_t* oV = reinterpret_cast<uint16_t*>(other.data[2] + (oy * other.stride[2])) + other.start_x;
927                 uint8_t* alpha = other.alpha_data[0] + (oy * other.alpha_stride[0]) + other.start_x * other.alpha_bpp;
928                 for (int tx = target.start_x, ox = other.start_x; tx < ts.width && ox < os.width; ++tx, ++ox) {
929                         float const a = get_alpha(alpha);
930                         *tY = *oY * a + *tY * (1 - a);
931                         *tU = *oU * a + *tU * (1 - a);
932                         *tV = *oV * a + *tV * (1 - a);
933                         ++tY;
934                         ++oY;
935                         ++tU;
936                         ++tV;
937                         ++oU;
938                         ++oV;
939                         alpha += other.alpha_bpp;
940                 }
941         }
942 }
943
944
945 void
946 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
947 {
948         DCPOMATIC_ASSERT(
949                 other->pixel_format() == AV_PIX_FMT_BGRA ||
950                 other->pixel_format() == AV_PIX_FMT_RGBA ||
951                 other->pixel_format() == AV_PIX_FMT_RGBA64BE
952                 );
953
954         int const blue = other->pixel_format() == AV_PIX_FMT_BGRA ? 0 : 2;
955         int const red = other->pixel_format() == AV_PIX_FMT_BGRA ? 2 : 0;
956
957         int start_tx = position.x;
958         int start_ox = 0;
959
960         if (start_tx < 0) {
961                 start_ox = -start_tx;
962                 start_tx = 0;
963         }
964
965         int start_ty = position.y;
966         int start_oy = 0;
967
968         if (start_ty < 0) {
969                 start_oy = -start_ty;
970                 start_ty = 0;
971         }
972
973         TargetParams target_params = {
974                 start_tx,
975                 start_ty,
976                 size(),
977                 data(),
978                 stride(),
979                 0
980         };
981
982         OtherRGBParams other_rgb_params = {
983                 start_ox,
984                 start_oy,
985                 other->size(),
986                 other->data(),
987                 other->stride(),
988                 other->pixel_format() == AV_PIX_FMT_RGBA64BE ? 8 : 4
989         };
990
991         OtherYUVParams other_yuv_params = {
992                 start_ox,
993                 start_oy,
994                 other->size(),
995                 other->data(),
996                 other->stride(),
997                 nullptr,
998                 nullptr,
999                 other->pixel_format() == AV_PIX_FMT_RGBA64BE ? 8 : 4
1000         };
1001
1002         auto byteswap = [](uint16_t* p) {
1003                 return (*p >> 8) | ((*p & 0xff) << 8);
1004         };
1005
1006         auto pass = [](uint8_t* p) {
1007                 return *p;
1008         };
1009
1010         auto get_alpha_64be = [](uint8_t* p) {
1011                 return ((static_cast<int16_t>(p[6]) << 8) | p[7]) / 65535.0f;
1012         };
1013
1014         auto get_alpha_byte = [](uint8_t* p) {
1015                 return p[3] / 255.0f;
1016         };
1017
1018         switch (_pixel_format) {
1019         case AV_PIX_FMT_RGB24:
1020                 target_params.bpp = 3;
1021                 if (other->pixel_format() == AV_PIX_FMT_RGBA64BE) {
1022                         alpha_blend_onto_rgb24<uint16_t>(target_params, other_rgb_params, red, blue, byteswap, 256);
1023                 } else {
1024                         alpha_blend_onto_rgb24<uint8_t>(target_params, other_rgb_params, red, blue, pass, 1);
1025                 }
1026                 break;
1027         case AV_PIX_FMT_BGRA:
1028                 target_params.bpp = 4;
1029                 if (other->pixel_format() == AV_PIX_FMT_RGBA64BE) {
1030                         alpha_blend_onto_bgra<uint16_t>(target_params, other_rgb_params, red, blue, byteswap, 256);
1031                 } else {
1032                         alpha_blend_onto_bgra<uint8_t>(target_params, other_rgb_params, red, blue, pass, 1);
1033                 }
1034                 break;
1035         case AV_PIX_FMT_RGBA:
1036                 target_params.bpp = 4;
1037                 if (other->pixel_format() == AV_PIX_FMT_RGBA64BE) {
1038                         alpha_blend_onto_rgba<uint16_t>(target_params, other_rgb_params, red, blue, byteswap, 256);
1039                 } else {
1040                         alpha_blend_onto_rgba<uint8_t>(target_params, other_rgb_params, red, blue, pass, 1);
1041                 }
1042                 break;
1043         case AV_PIX_FMT_RGB48LE:
1044                 target_params.bpp = 6;
1045                 if (other->pixel_format() == AV_PIX_FMT_RGBA64BE) {
1046                         alpha_blend_onto_rgb48le<uint16_t>(target_params, other_rgb_params, red, blue, byteswap, 1);
1047                 } else {
1048                         alpha_blend_onto_rgb48le<uint8_t>(target_params, other_rgb_params, red, blue, pass, 256);
1049                 }
1050                 break;
1051         case AV_PIX_FMT_XYZ12LE:
1052                 target_params.bpp = 6;
1053                 if (other->pixel_format() == AV_PIX_FMT_RGBA64BE) {
1054                         alpha_blend_onto_xyz12le<uint16_t>(target_params, other_rgb_params, red, blue, byteswap, 256);
1055                 } else {
1056                         alpha_blend_onto_xyz12le<uint8_t>(target_params, other_rgb_params, red, blue, pass, 1);
1057                 }
1058                 break;
1059         case AV_PIX_FMT_YUV420P:
1060         {
1061                 auto yuv = other->convert_pixel_format (dcp::YUVToRGB::REC709, _pixel_format, Alignment::COMPACT, false);
1062                 other_yuv_params.data = yuv->data();
1063                 other_yuv_params.stride = yuv->stride();
1064                 other_yuv_params.alpha_data = other->data();
1065                 other_yuv_params.alpha_stride = other->stride();
1066                 if (other->pixel_format() == AV_PIX_FMT_RGBA64BE) {
1067                         alpha_blend_onto_yuv420p(target_params, other_yuv_params, get_alpha_64be);
1068                 } else {
1069                         alpha_blend_onto_yuv420p(target_params, other_yuv_params, get_alpha_byte);
1070                 }
1071                 break;
1072         }
1073         case AV_PIX_FMT_YUV420P10:
1074         {
1075                 auto yuv = other->convert_pixel_format (dcp::YUVToRGB::REC709, _pixel_format, Alignment::COMPACT, false);
1076                 other_yuv_params.data = yuv->data();
1077                 other_yuv_params.stride = yuv->stride();
1078                 other_yuv_params.alpha_data = other->data();
1079                 other_yuv_params.alpha_stride = other->stride();
1080                 if (other->pixel_format() == AV_PIX_FMT_RGBA64BE) {
1081                         alpha_blend_onto_yuv420p10(target_params, other_yuv_params, get_alpha_64be);
1082                 } else {
1083                         alpha_blend_onto_yuv420p10(target_params, other_yuv_params, get_alpha_byte);
1084                 }
1085                 break;
1086         }
1087         case AV_PIX_FMT_YUV422P9LE:
1088         case AV_PIX_FMT_YUV422P10LE:
1089         {
1090                 auto yuv = other->convert_pixel_format (dcp::YUVToRGB::REC709, _pixel_format, Alignment::COMPACT, false);
1091                 other_yuv_params.data = yuv->data();
1092                 other_yuv_params.stride = yuv->stride();
1093                 other_yuv_params.alpha_data = other->data();
1094                 other_yuv_params.alpha_stride = other->stride();
1095                 if (other->pixel_format() == AV_PIX_FMT_RGBA64BE) {
1096                         alpha_blend_onto_yuv422p9or10le(target_params, other_yuv_params, get_alpha_64be);
1097                 } else {
1098                         alpha_blend_onto_yuv422p9or10le(target_params, other_yuv_params, get_alpha_byte);
1099                 }
1100                 break;
1101         }
1102         case AV_PIX_FMT_YUV444P9LE:
1103         case AV_PIX_FMT_YUV444P10LE:
1104         {
1105                 auto yuv = other->convert_pixel_format (dcp::YUVToRGB::REC709, _pixel_format, Alignment::COMPACT, false);
1106                 other_yuv_params.data = yuv->data();
1107                 other_yuv_params.stride = yuv->stride();
1108                 other_yuv_params.alpha_data = other->data();
1109                 other_yuv_params.alpha_stride = other->stride();
1110                 if (other->pixel_format() == AV_PIX_FMT_RGBA64BE) {
1111                         alpha_blend_onto_yuv444p9or10le(target_params, other_yuv_params, get_alpha_64be);
1112                 } else {
1113                         alpha_blend_onto_yuv444p9or10le(target_params, other_yuv_params, get_alpha_byte);
1114                 }
1115                 break;
1116         }
1117         default:
1118                 throw PixelFormatError ("alpha_blend()", _pixel_format);
1119         }
1120 }
1121
1122
1123 void
1124 Image::copy (shared_ptr<const Image> other, Position<int> position)
1125 {
1126         /* Only implemented for RGB24 onto RGB24 so far */
1127         DCPOMATIC_ASSERT (_pixel_format == AV_PIX_FMT_RGB24 && other->pixel_format() == AV_PIX_FMT_RGB24);
1128         DCPOMATIC_ASSERT (position.x >= 0 && position.y >= 0);
1129
1130         int const N = min (position.x + other->size().width, size().width) - position.x;
1131         for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
1132                 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
1133                 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
1134                 memcpy (tp, op, N * 3);
1135         }
1136 }
1137
1138
1139 void
1140 Image::read_from_socket (shared_ptr<Socket> socket)
1141 {
1142         for (int i = 0; i < planes(); ++i) {
1143                 uint8_t* p = data()[i];
1144                 int const lines = sample_size(i).height;
1145                 for (int y = 0; y < lines; ++y) {
1146                         socket->read (p, line_size()[i]);
1147                         p += stride()[i];
1148                 }
1149         }
1150 }
1151
1152
1153 void
1154 Image::write_to_socket (shared_ptr<Socket> socket) const
1155 {
1156         for (int i = 0; i < planes(); ++i) {
1157                 uint8_t* p = data()[i];
1158                 int const lines = sample_size(i).height;
1159                 for (int y = 0; y < lines; ++y) {
1160                         socket->write (p, line_size()[i]);
1161                         p += stride()[i];
1162                 }
1163         }
1164 }
1165
1166
1167 float
1168 Image::bytes_per_pixel (int c) const
1169 {
1170         auto d = av_pix_fmt_desc_get(_pixel_format);
1171         if (!d) {
1172                 throw PixelFormatError ("bytes_per_pixel()", _pixel_format);
1173         }
1174
1175         if (c >= planes()) {
1176                 return 0;
1177         }
1178
1179         float bpp[4] = { 0, 0, 0, 0 };
1180
1181 #ifdef DCPOMATIC_HAVE_AVCOMPONENTDESCRIPTOR_DEPTH_MINUS1
1182         bpp[0] = floor ((d->comp[0].depth_minus1 + 8) / 8);
1183         if (d->nb_components > 1) {
1184                 bpp[1] = floor ((d->comp[1].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
1185         }
1186         if (d->nb_components > 2) {
1187                 bpp[2] = floor ((d->comp[2].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
1188         }
1189         if (d->nb_components > 3) {
1190                 bpp[3] = floor ((d->comp[3].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
1191         }
1192 #else
1193         bpp[0] = floor ((d->comp[0].depth + 7) / 8);
1194         if (d->nb_components > 1) {
1195                 bpp[1] = floor ((d->comp[1].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
1196         }
1197         if (d->nb_components > 2) {
1198                 bpp[2] = floor ((d->comp[2].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
1199         }
1200         if (d->nb_components > 3) {
1201                 bpp[3] = floor ((d->comp[3].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
1202         }
1203 #endif
1204
1205         if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
1206                 /* Not planar; sum them up */
1207                 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
1208         }
1209
1210         return bpp[c];
1211 }
1212
1213
1214 /** Construct a Image of a given size and format, allocating memory
1215  *  as required.
1216  *
1217  *  @param p Pixel format.
1218  *  @param s Size in pixels.
1219  *  @param alignment PADDED to make each row of this image aligned to a ALIGNMENT-byte boundary, otherwise COMPACT.
1220  */
1221 Image::Image (AVPixelFormat p, dcp::Size s, Alignment alignment)
1222         : _size (s)
1223         , _pixel_format (p)
1224         , _alignment (alignment)
1225 {
1226         allocate ();
1227 }
1228
1229
1230 void
1231 Image::allocate ()
1232 {
1233         _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
1234         _data[0] = _data[1] = _data[2] = _data[3] = 0;
1235
1236         _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
1237         _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
1238
1239         _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
1240         _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
1241
1242         auto stride_round_up = [](int stride, int t) {
1243                 int const a = stride + (t - 1);
1244                 return a - (a % t);
1245         };
1246
1247         for (int i = 0; i < planes(); ++i) {
1248                 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
1249                 _stride[i] = stride_round_up (_line_size[i], _alignment == Alignment::PADDED ? ALIGNMENT : 1);
1250
1251                 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
1252                    uses a 16-byte fetch to read three bytes (R/G/B) of image data.
1253                    Hence on the last pixel of the last line it reads over the end of
1254                    the actual data by 1 byte.  If the width of an image is a multiple
1255                    of the stride alignment there will be no padding at the end of image lines.
1256                    OS X crashes on this illegal read, though other operating systems don't
1257                    seem to mind.  The nasty + 1 in this malloc makes sure there is always a byte
1258                    for that instruction to read safely.
1259
1260                    Further to the above, valgrind is now telling me that ff_rgb24ToY_ssse3
1261                    over-reads by more then _avx.  I can't follow the code to work out how much,
1262                    so I'll just over-allocate by ALIGNMENT bytes and have done with it.  Empirical
1263                    testing suggests that it works.
1264
1265                    In addition to these concerns, we may read/write as much as a whole extra line
1266                    at the end of each plane in cases where we are messing with offsets in order to
1267                    do pad or crop.  To solve this we over-allocate by an extra _stride[i] bytes.
1268
1269                    As an example: we may write to images starting at an offset so we get some padding.
1270                    Hence we want to write in the following pattern:
1271
1272                    block start   write start                                  line end
1273                    |..(padding)..|<------line-size------------->|..(padding)..|
1274                    |..(padding)..|<------line-size------------->|..(padding)..|
1275                    |..(padding)..|<------line-size------------->|..(padding)..|
1276
1277                    where line-size is of the smaller (inter_size) image and the full padded line length is that of
1278                    out_size.  To get things to work we have to tell FFmpeg that the stride is that of out_size.
1279                    However some parts of FFmpeg (notably rgb48Toxyz12 in swscale.c) process data for the full
1280                    specified *stride*.  This does not matter until we get to the last line:
1281
1282                    block start   write start                                  line end
1283                    |..(padding)..|<------line-size------------->|XXXwrittenXXX|
1284                    |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXX|
1285                    |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXXXXXwrittenXXX
1286                                                                                ^^^^ out of bounds
1287                 */
1288                 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * (sample_size(i).height + 1) + ALIGNMENT);
1289 #if HAVE_VALGRIND_MEMCHECK_H
1290                 /* The data between the end of the line size and the stride is undefined but processed by
1291                    libswscale, causing lots of valgrind errors.  Mark it all defined to quell these errors.
1292                 */
1293                 VALGRIND_MAKE_MEM_DEFINED (_data[i], _stride[i] * (sample_size(i).height + 1) + ALIGNMENT);
1294 #endif
1295         }
1296 }
1297
1298
1299 Image::Image (Image const & other)
1300         : std::enable_shared_from_this<Image>(other)
1301         , _size (other._size)
1302         , _pixel_format (other._pixel_format)
1303         , _alignment (other._alignment)
1304 {
1305         allocate ();
1306
1307         for (int i = 0; i < planes(); ++i) {
1308                 uint8_t* p = _data[i];
1309                 uint8_t* q = other._data[i];
1310                 int const lines = sample_size(i).height;
1311                 for (int j = 0; j < lines; ++j) {
1312                         memcpy (p, q, _line_size[i]);
1313                         p += stride()[i];
1314                         q += other.stride()[i];
1315                 }
1316         }
1317 }
1318
1319
1320 Image::Image (AVFrame const * frame, Alignment alignment)
1321         : _size (frame->width, frame->height)
1322         , _pixel_format (static_cast<AVPixelFormat>(frame->format))
1323         , _alignment (alignment)
1324 {
1325         DCPOMATIC_ASSERT (_pixel_format != AV_PIX_FMT_NONE);
1326
1327         allocate ();
1328
1329         for (int i = 0; i < planes(); ++i) {
1330                 uint8_t* p = _data[i];
1331                 uint8_t* q = frame->data[i];
1332                 int const lines = sample_size(i).height;
1333                 for (int j = 0; j < lines; ++j) {
1334                         memcpy (p, q, _line_size[i]);
1335                         p += stride()[i];
1336                         /* AVFrame's linesize is what we call `stride' */
1337                         q += frame->linesize[i];
1338                 }
1339         }
1340 }
1341
1342
1343 Image::Image (shared_ptr<const Image> other, Alignment alignment)
1344         : _size (other->_size)
1345         , _pixel_format (other->_pixel_format)
1346         , _alignment (alignment)
1347 {
1348         allocate ();
1349
1350         for (int i = 0; i < planes(); ++i) {
1351                 DCPOMATIC_ASSERT (line_size()[i] == other->line_size()[i]);
1352                 uint8_t* p = _data[i];
1353                 uint8_t* q = other->data()[i];
1354                 int const lines = sample_size(i).height;
1355                 for (int j = 0; j < lines; ++j) {
1356                         memcpy (p, q, line_size()[i]);
1357                         p += stride()[i];
1358                         q += other->stride()[i];
1359                 }
1360         }
1361 }
1362
1363
1364 Image&
1365 Image::operator= (Image const & other)
1366 {
1367         if (this == &other) {
1368                 return *this;
1369         }
1370
1371         Image tmp (other);
1372         swap (tmp);
1373         return *this;
1374 }
1375
1376
1377 void
1378 Image::swap (Image & other)
1379 {
1380         std::swap (_size, other._size);
1381         std::swap (_pixel_format, other._pixel_format);
1382
1383         for (int i = 0; i < 4; ++i) {
1384                 std::swap (_data[i], other._data[i]);
1385                 std::swap (_line_size[i], other._line_size[i]);
1386                 std::swap (_stride[i], other._stride[i]);
1387         }
1388
1389         std::swap (_alignment, other._alignment);
1390 }
1391
1392
1393 Image::~Image ()
1394 {
1395         for (int i = 0; i < planes(); ++i) {
1396                 av_free (_data[i]);
1397         }
1398
1399         av_free (_data);
1400         av_free (_line_size);
1401         av_free (_stride);
1402 }
1403
1404
1405 uint8_t * const *
1406 Image::data () const
1407 {
1408         return _data;
1409 }
1410
1411
1412 int const *
1413 Image::line_size () const
1414 {
1415         return _line_size;
1416 }
1417
1418
1419 int const *
1420 Image::stride () const
1421 {
1422         return _stride;
1423 }
1424
1425
1426 dcp::Size
1427 Image::size () const
1428 {
1429         return _size;
1430 }
1431
1432
1433 Image::Alignment
1434 Image::alignment () const
1435 {
1436         return _alignment;
1437 }
1438
1439
1440 PositionImage
1441 merge (list<PositionImage> images, Image::Alignment alignment)
1442 {
1443         if (images.empty ()) {
1444                 return {};
1445         }
1446
1447         if (images.size() == 1) {
1448                 images.front().image = Image::ensure_alignment(images.front().image, alignment);
1449                 return images.front();
1450         }
1451
1452         dcpomatic::Rect<int> all (images.front().position, images.front().image->size().width, images.front().image->size().height);
1453         for (auto const& i: images) {
1454                 all.extend (dcpomatic::Rect<int>(i.position, i.image->size().width, i.image->size().height));
1455         }
1456
1457         auto merged = make_shared<Image>(images.front().image->pixel_format(), dcp::Size(all.width, all.height), alignment);
1458         merged->make_transparent ();
1459         for (auto const& i: images) {
1460                 merged->alpha_blend (i.image, i.position - all.position());
1461         }
1462
1463         return PositionImage (merged, all.position ());
1464 }
1465
1466
1467 bool
1468 operator== (Image const & a, Image const & b)
1469 {
1470         if (a.planes() != b.planes() || a.pixel_format() != b.pixel_format() || a.alignment() != b.alignment()) {
1471                 return false;
1472         }
1473
1474         for (int c = 0; c < a.planes(); ++c) {
1475                 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]) {
1476                         return false;
1477                 }
1478
1479                 uint8_t* p = a.data()[c];
1480                 uint8_t* q = b.data()[c];
1481                 int const lines = a.sample_size(c).height;
1482                 for (int y = 0; y < lines; ++y) {
1483                         if (memcmp (p, q, a.line_size()[c]) != 0) {
1484                                 return false;
1485                         }
1486
1487                         p += a.stride()[c];
1488                         q += b.stride()[c];
1489                 }
1490         }
1491
1492         return true;
1493 }
1494
1495
1496 /** Fade the image.
1497  *  @param f Amount to fade by; 0 is black, 1 is no fade.
1498  */
1499 void
1500 Image::fade (float f)
1501 {
1502         /* U/V black value for 8-bit colour */
1503         static int const eight_bit_uv =    (1 << 7) - 1;
1504         /* U/V black value for 10-bit colour */
1505         static uint16_t const ten_bit_uv = (1 << 9) - 1;
1506
1507         switch (_pixel_format) {
1508         case AV_PIX_FMT_YUV420P:
1509         {
1510                 /* Y */
1511                 uint8_t* p = data()[0];
1512                 int const lines = sample_size(0).height;
1513                 for (int y = 0; y < lines; ++y) {
1514                         uint8_t* q = p;
1515                         for (int x = 0; x < line_size()[0]; ++x) {
1516                                 *q = int(float(*q) * f);
1517                                 ++q;
1518                         }
1519                         p += stride()[0];
1520                 }
1521
1522                 /* U, V */
1523                 for (int c = 1; c < 3; ++c) {
1524                         uint8_t* p = data()[c];
1525                         int const lines = sample_size(c).height;
1526                         for (int y = 0; y < lines; ++y) {
1527                                 uint8_t* q = p;
1528                                 for (int x = 0; x < line_size()[c]; ++x) {
1529                                         *q = eight_bit_uv + int((int(*q) - eight_bit_uv) * f);
1530                                         ++q;
1531                                 }
1532                                 p += stride()[c];
1533                         }
1534                 }
1535
1536                 break;
1537         }
1538
1539         case AV_PIX_FMT_RGB24:
1540         {
1541                 /* 8-bit */
1542                 uint8_t* p = data()[0];
1543                 int const lines = sample_size(0).height;
1544                 for (int y = 0; y < lines; ++y) {
1545                         uint8_t* q = p;
1546                         for (int x = 0; x < line_size()[0]; ++x) {
1547                                 *q = int (float (*q) * f);
1548                                 ++q;
1549                         }
1550                         p += stride()[0];
1551                 }
1552                 break;
1553         }
1554
1555         case AV_PIX_FMT_XYZ12LE:
1556         case AV_PIX_FMT_RGB48LE:
1557                 /* 16-bit little-endian */
1558                 for (int c = 0; c < 3; ++c) {
1559                         int const stride_pixels = stride()[c] / 2;
1560                         int const line_size_pixels = line_size()[c] / 2;
1561                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1562                         int const lines = sample_size(c).height;
1563                         for (int y = 0; y < lines; ++y) {
1564                                 uint16_t* q = p;
1565                                 for (int x = 0; x < line_size_pixels; ++x) {
1566                                         *q = int (float (*q) * f);
1567                                         ++q;
1568                                 }
1569                                 p += stride_pixels;
1570                         }
1571                 }
1572                 break;
1573
1574         case AV_PIX_FMT_YUV422P10LE:
1575         {
1576                 /* Y */
1577                 {
1578                         int const stride_pixels = stride()[0] / 2;
1579                         int const line_size_pixels = line_size()[0] / 2;
1580                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[0]);
1581                         int const lines = sample_size(0).height;
1582                         for (int y = 0; y < lines; ++y) {
1583                                 uint16_t* q = p;
1584                                 for (int x = 0; x < line_size_pixels; ++x) {
1585                                         *q = int(float(*q) * f);
1586                                         ++q;
1587                                 }
1588                                 p += stride_pixels;
1589                         }
1590                 }
1591
1592                 /* U, V */
1593                 for (int c = 1; c < 3; ++c) {
1594                         int const stride_pixels = stride()[c] / 2;
1595                         int const line_size_pixels = line_size()[c] / 2;
1596                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1597                         int const lines = sample_size(c).height;
1598                         for (int y = 0; y < lines; ++y) {
1599                                 uint16_t* q = p;
1600                                 for (int x = 0; x < line_size_pixels; ++x) {
1601                                         *q = ten_bit_uv + int((int(*q) - ten_bit_uv) * f);
1602                                         ++q;
1603                                 }
1604                                 p += stride_pixels;
1605                         }
1606                 }
1607                 break;
1608
1609         }
1610
1611         default:
1612                 throw PixelFormatError ("fade()", _pixel_format);
1613         }
1614 }
1615
1616
1617 shared_ptr<const Image>
1618 Image::ensure_alignment (shared_ptr<const Image> image, Image::Alignment alignment)
1619 {
1620         if (image->alignment() == alignment) {
1621                 return image;
1622         }
1623
1624         return make_shared<Image>(image, alignment);
1625 }
1626
1627
1628 size_t
1629 Image::memory_used () const
1630 {
1631         size_t m = 0;
1632         for (int i = 0; i < planes(); ++i) {
1633                 m += _stride[i] * sample_size(i).height;
1634         }
1635         return m;
1636 }
1637
1638
1639 void
1640 Image::video_range_to_full_range ()
1641 {
1642         switch (_pixel_format) {
1643         case AV_PIX_FMT_RGB24:
1644         {
1645                 float const factor = 256.0 / 219.0;
1646                 uint8_t* p = data()[0];
1647                 int const lines = sample_size(0).height;
1648                 for (int y = 0; y < lines; ++y) {
1649                         uint8_t* q = p;
1650                         for (int x = 0; x < line_size()[0]; ++x) {
1651                                 *q = clamp(lrintf((*q - 16) * factor), 0L, 255L);
1652                                 ++q;
1653                         }
1654                         p += stride()[0];
1655                 }
1656                 break;
1657         }
1658         case AV_PIX_FMT_RGB48LE:
1659         {
1660                 float const factor = 65536.0 / 56064.0;
1661                 uint16_t* p = reinterpret_cast<uint16_t*>(data()[0]);
1662                 int const lines = sample_size(0).height;
1663                 for (int y = 0; y < lines; ++y) {
1664                         uint16_t* q = p;
1665                         int const line_size_pixels = line_size()[0] / 2;
1666                         for (int x = 0; x < line_size_pixels; ++x) {
1667                                 *q = clamp(lrintf((*q - 4096) * factor), 0L, 65535L);
1668                                 ++q;
1669                         }
1670                         p += stride()[0] / 2;
1671                 }
1672                 break;
1673         }
1674         case AV_PIX_FMT_GBRP12LE:
1675         {
1676                 float const factor = 4096.0 / 3504.0;
1677                 for (int c = 0; c < 3; ++c) {
1678                         uint16_t* p = reinterpret_cast<uint16_t*>(data()[c]);
1679                         int const lines = sample_size(c).height;
1680                         for (int y = 0; y < lines; ++y) {
1681                                 uint16_t* q = p;
1682                                 int const line_size_pixels = line_size()[c] / 2;
1683                                 for (int x = 0; x < line_size_pixels; ++x) {
1684                                         *q = clamp(lrintf((*q - 256) * factor), 0L, 4095L);
1685                                         ++q;
1686                                 }
1687                         }
1688                 }
1689                 break;
1690         }
1691         default:
1692                 throw PixelFormatError ("video_range_to_full_range()", _pixel_format);
1693         }
1694 }
1695