4042d5886df28ccd3386e98e3acb237918a97216
[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 };
677
678
679 template <class OtherType>
680 void
681 alpha_blend_onto_rgb24(TargetParams const& target, OtherRGBParams const& other, int red, int blue, std::function<float (OtherType*)> get, int value_divisor)
682 {
683         /* Going onto RGB24.  First byte is red, second green, third blue */
684         auto const alpha_divisor = other.alpha_divisor();
685         for (int ty = target.start_y, oy = other.start_y; ty < target.size.height && oy < other.size.height; ++ty, ++oy) {
686                 auto tp = target.line_pointer(ty);
687                 auto op = reinterpret_cast<OtherType*>(other.line_pointer(oy));
688                 for (int tx = target.start_x, ox = other.start_x; tx < target.size.width && ox < other.size.width; ++tx, ++ox) {
689                         float const alpha = get(op + 3) / alpha_divisor;
690                         tp[0] = (get(op + red) / value_divisor) * alpha + tp[0] * (1 - alpha);
691                         tp[1] = (get(op + 1) / value_divisor) * alpha + tp[1] * (1 - alpha);
692                         tp[2] = (get(op + blue) / value_divisor) * alpha + tp[2] * (1 - alpha);
693
694                         tp += target.bpp;
695                         op += other.bpp / sizeof(OtherType);
696                 }
697         }
698 }
699
700
701 template <class OtherType>
702 void
703 alpha_blend_onto_bgra(TargetParams const& target, OtherRGBParams const& other, int red, int blue, std::function<float (OtherType*)> get, int value_divisor)
704 {
705         auto const alpha_divisor = other.alpha_divisor();
706         for (int ty = target.start_y, oy = other.start_y; ty < target.size.height && oy < other.size.height; ++ty, ++oy) {
707                 auto tp = target.line_pointer(ty);
708                 auto op = reinterpret_cast<OtherType*>(other.line_pointer(oy));
709                 for (int tx = target.start_x, ox = other.start_x; tx < target.size.width && ox < other.size.width; ++tx, ++ox) {
710                         float const alpha = get(op + 3) / alpha_divisor;
711                         tp[0] = (get(op + blue) / value_divisor) * alpha + tp[0] * (1 - alpha);
712                         tp[1] = (get(op + 1) / value_divisor) * alpha + tp[1] * (1 - alpha);
713                         tp[2] = (get(op + red) / value_divisor) * alpha + tp[2] * (1 - alpha);
714                         tp[3] = (get(op + 3) / value_divisor) * alpha + tp[3] * (1 - alpha);
715
716                         tp += target.bpp;
717                         op += other.bpp / sizeof(OtherType);
718                 }
719         }
720 }
721
722
723 template <class OtherType>
724 void
725 alpha_blend_onto_rgba(TargetParams const& target, OtherRGBParams const& other, int red, int blue, std::function<float (OtherType*)> get, int value_divisor)
726 {
727         auto const alpha_divisor = other.alpha_divisor();
728         for (int ty = target.start_y, oy = other.start_y; ty < target.size.height && oy < other.size.height; ++ty, ++oy) {
729                 auto tp = target.line_pointer(ty);
730                 auto op = reinterpret_cast<OtherType*>(other.line_pointer(oy));
731                 for (int tx = target.start_x, ox = other.start_x; tx < target.size.width && ox < other.size.width; ++tx, ++ox) {
732                         float const alpha = get(op + 3) / alpha_divisor;
733                         tp[0] = (get(op + red) / value_divisor) * alpha + tp[0] * (1 - alpha);
734                         tp[1] = (get(op + 1) / value_divisor) * alpha + tp[1] * (1 - alpha);
735                         tp[2] = (get(op + blue) / value_divisor) * alpha + tp[2] * (1 - alpha);
736                         tp[3] = (get(op + 3) / value_divisor) * alpha + tp[3] * (1 - alpha);
737
738                         tp += target.bpp;
739                         op += other.bpp / sizeof(OtherType);
740                 }
741         }
742 }
743
744
745 template <class OtherType>
746 void
747 alpha_blend_onto_rgb48le(TargetParams const& target, OtherRGBParams const& other, int red, int blue, std::function<float (OtherType*)> get, int value_scale)
748 {
749         auto const alpha_divisor = other.alpha_divisor();
750         for (int ty = target.start_y, oy = other.start_y; ty < target.size.height && oy < other.size.height; ++ty, ++oy) {
751                 auto tp = reinterpret_cast<uint16_t*>(target.line_pointer(ty));
752                 auto op = reinterpret_cast<OtherType*>(other.line_pointer(oy));
753                 for (int tx = target.start_x, ox = other.start_x; tx < target.size.width && ox < other.size.width; ++tx, ++ox) {
754                         float const alpha = get(op + 3) / alpha_divisor;
755                         tp[0] = get(op + red) * value_scale * alpha + tp[0] * (1 - alpha);
756                         tp[1] = get(op + 1) * value_scale * alpha + tp[1] * (1 - alpha);
757                         tp[2] = get(op + blue) * value_scale * alpha + tp[2] * (1 - alpha);
758
759                         tp += target.bpp / 2;
760                         op += other.bpp / sizeof(OtherType);
761                 }
762         }
763 }
764
765
766 template <class OtherType>
767 void
768 alpha_blend_onto_xyz12le(TargetParams const& target, OtherRGBParams const& other, int red, int blue, std::function<float (OtherType*)> get, int value_divisor)
769 {
770         auto const alpha_divisor = other.alpha_divisor();
771         auto conv = dcp::ColourConversion::srgb_to_xyz();
772         double fast_matrix[9];
773         dcp::combined_rgb_to_xyz(conv, fast_matrix);
774         auto lut_in = conv.in()->double_lut(0, 1, 8, false);
775         auto lut_out = conv.out()->int_lut(0, 1, 16, true, 65535);
776         for (int ty = target.start_y, oy = other.start_y; ty < target.size.height && oy < other.size.height; ++ty, ++oy) {
777                 auto tp = reinterpret_cast<uint16_t*>(target.data[0] + ty * target.stride[0] + target.start_x * target.bpp);
778                 auto op = reinterpret_cast<OtherType*>(other.data[0] + oy * other.stride[0]);
779                 for (int tx = target.start_x, ox = other.start_x; tx < target.size.width && ox < other.size.width; ++tx, ++ox) {
780                         float const alpha = get(op + 3) / alpha_divisor;
781
782                         /* Convert sRGB to XYZ; op is BGRA.  First, input gamma LUT */
783                         double const r = lut_in[get(op + red) / value_divisor];
784                         double const g = lut_in[get(op + 1) / value_divisor];
785                         double const b = lut_in[get(op + blue) / value_divisor];
786
787                         /* RGB to XYZ, including Bradford transform and DCI companding */
788                         double const x = max(0.0, min(1.0, r * fast_matrix[0] + g * fast_matrix[1] + b * fast_matrix[2]));
789                         double const y = max(0.0, min(1.0, r * fast_matrix[3] + g * fast_matrix[4] + b * fast_matrix[5]));
790                         double const z = max(0.0, min(1.0, r * fast_matrix[6] + g * fast_matrix[7] + b * fast_matrix[8]));
791
792                         /* Out gamma LUT and blend */
793                         tp[0] = lut_out[lrint(x * 65535)] * alpha + tp[0] * (1 - alpha);
794                         tp[1] = lut_out[lrint(y * 65535)] * alpha + tp[1] * (1 - alpha);
795                         tp[2] = lut_out[lrint(z * 65535)] * alpha + tp[2] * (1 - alpha);
796
797                         tp += target.bpp / 2;
798                         op += other.bpp / sizeof(OtherType);
799                 }
800         }
801 }
802
803
804 static
805 void
806 alpha_blend_onto_yuv420p(TargetParams const& target, OtherYUVParams const& other)
807 {
808         auto const ts = target.size;
809         auto const os = other.size;
810         for (int ty = target.start_y, oy = other.start_y; ty < ts.height && oy < os.height; ++ty, ++oy) {
811                 int const hty = ty / 2;
812                 int const hoy = oy / 2;
813                 uint8_t* tY = target.data[0] + (ty * target.stride[0]) + target.start_x;
814                 uint8_t* tU = target.data[1] + (hty * target.stride[1]) + target.start_x / 2;
815                 uint8_t* tV = target.data[2] + (hty * target.stride[2]) + target.start_x / 2;
816                 uint8_t* oY = other.data[0] + (oy * other.stride[0]) + other.start_x;
817                 uint8_t* oU = other.data[1] + (hoy * other.stride[1]) + other.start_x / 2;
818                 uint8_t* oV = other.data[2] + (hoy * other.stride[2]) + other.start_x / 2;
819                 uint8_t* alpha = other.alpha_data[0] + (oy * other.alpha_stride[0]) + other.start_x * 4;
820                 for (int tx = target.start_x, ox = other.start_x; tx < ts.width && ox < os.width; ++tx, ++ox) {
821                         float const a = float(alpha[3]) / 255;
822                         *tY = *oY * a + *tY * (1 - a);
823                         *tU = *oU * a + *tU * (1 - a);
824                         *tV = *oV * a + *tV * (1 - a);
825                         ++tY;
826                         ++oY;
827                         if (tx % 2) {
828                                 ++tU;
829                                 ++tV;
830                         }
831                         if (ox % 2) {
832                                 ++oU;
833                                 ++oV;
834                         }
835                         alpha += 4;
836                 }
837         }
838 }
839
840
841 static
842 void
843 alpha_blend_onto_yuv420p10(TargetParams const& target, OtherYUVParams const& other)
844 {
845         auto const ts = target.size;
846         auto const os = other.size;
847         for (int ty = target.start_y, oy = other.start_y; ty < ts.height && oy < os.height; ++ty, ++oy) {
848                 int const hty = ty / 2;
849                 int const hoy = oy / 2;
850                 uint16_t* tY = reinterpret_cast<uint16_t*>(target.data[0] + (ty * target.stride[0])) + target.start_x;
851                 uint16_t* tU = reinterpret_cast<uint16_t*>(target.data[1] + (hty * target.stride[1])) + target.start_x / 2;
852                 uint16_t* tV = reinterpret_cast<uint16_t*>(target.data[2] + (hty * target.stride[2])) + target.start_x / 2;
853                 uint16_t* oY = reinterpret_cast<uint16_t*>(other.data[0] + (oy * other.stride[0])) + other.start_x;
854                 uint16_t* oU = reinterpret_cast<uint16_t*>(other.data[1] + (hoy * other.stride[1])) + other.start_x / 2;
855                 uint16_t* oV = reinterpret_cast<uint16_t*>(other.data[2] + (hoy * other.stride[2])) + other.start_x / 2;
856                 uint8_t* alpha = other.alpha_data[0] + (oy * other.alpha_stride[0]) + other.start_x * 4;
857                 for (int tx = target.start_x, ox = other.start_x; tx < ts.width && ox < os.width; ++tx, ++ox) {
858                         float const a = float(alpha[3]) / 255;
859                         *tY = *oY * a + *tY * (1 - a);
860                         *tU = *oU * a + *tU * (1 - a);
861                         *tV = *oV * a + *tV * (1 - a);
862                         ++tY;
863                         ++oY;
864                         if (tx % 2) {
865                                 ++tU;
866                                 ++tV;
867                         }
868                         if (ox % 2) {
869                                 ++oU;
870                                 ++oV;
871                         }
872                         alpha += 4;
873                 }
874         }
875 }
876
877
878 static
879 void
880 alpha_blend_onto_yuv422p9or10le(TargetParams const& target, OtherYUVParams const& other)
881 {
882         auto const ts = target.size;
883         auto const os = other.size;
884         for (int ty = target.start_y, oy = other.start_y; ty < ts.height && oy < os.height; ++ty, ++oy) {
885                 uint16_t* tY = reinterpret_cast<uint16_t*>(target.data[0] + (ty * target.stride[0])) + target.start_x;
886                 uint16_t* tU = reinterpret_cast<uint16_t*>(target.data[1] + (ty * target.stride[1])) + target.start_x / 2;
887                 uint16_t* tV = reinterpret_cast<uint16_t*>(target.data[2] + (ty * target.stride[2])) + target.start_x / 2;
888                 uint16_t* oY = reinterpret_cast<uint16_t*>(other.data[0] + (oy * other.stride[0])) + other.start_x;
889                 uint16_t* oU = reinterpret_cast<uint16_t*>(other.data[1] + (oy * other.stride[1])) + other.start_x / 2;
890                 uint16_t* oV = reinterpret_cast<uint16_t*>(other.data[2] + (oy * other.stride[2])) + other.start_x / 2;
891                 uint8_t* alpha = other.alpha_data[0] + (oy * other.alpha_stride[0]) + other.start_x * 4;
892                 for (int tx = target.start_x, ox = other.start_x; tx < ts.width && ox < os.width; ++tx, ++ox) {
893                         float const a = float(alpha[3]) / 255;
894                         *tY = *oY * a + *tY * (1 - a);
895                         *tU = *oU * a + *tU * (1 - a);
896                         *tV = *oV * a + *tV * (1 - a);
897                         ++tY;
898                         ++oY;
899                         if (tx % 2) {
900                                 ++tU;
901                                 ++tV;
902                         }
903                         if (ox % 2) {
904                                 ++oU;
905                                 ++oV;
906                         }
907                         alpha += 4;
908                 }
909         }
910 }
911
912
913 void
914 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
915 {
916         DCPOMATIC_ASSERT(
917                 other->pixel_format() == AV_PIX_FMT_BGRA ||
918                 other->pixel_format() == AV_PIX_FMT_RGBA ||
919                 other->pixel_format() == AV_PIX_FMT_RGBA64BE
920                 );
921
922         int const blue = other->pixel_format() == AV_PIX_FMT_BGRA ? 0 : 2;
923         int const red = other->pixel_format() == AV_PIX_FMT_BGRA ? 2 : 0;
924
925         int start_tx = position.x;
926         int start_ox = 0;
927
928         if (start_tx < 0) {
929                 start_ox = -start_tx;
930                 start_tx = 0;
931         }
932
933         int start_ty = position.y;
934         int start_oy = 0;
935
936         if (start_ty < 0) {
937                 start_oy = -start_ty;
938                 start_ty = 0;
939         }
940
941         TargetParams target_params = {
942                 start_tx,
943                 start_ty,
944                 size(),
945                 data(),
946                 stride(),
947                 0
948         };
949
950         OtherRGBParams other_rgb_params = {
951                 start_ox,
952                 start_oy,
953                 other->size(),
954                 other->data(),
955                 other->stride(),
956                 other->pixel_format() == AV_PIX_FMT_RGBA64BE ? 8 : 4
957         };
958
959         OtherYUVParams other_yuv_params = {
960                 start_ox,
961                 start_oy,
962                 other->size(),
963                 other->data(),
964                 other->stride(),
965                 nullptr,
966                 nullptr
967         };
968
969         auto byteswap = [](uint16_t* p) {
970                 return (*p >> 8) | ((*p & 0xff) << 8);
971         };
972
973         auto pass = [](uint8_t* p) {
974                 return *p;
975         };
976
977         switch (_pixel_format) {
978         case AV_PIX_FMT_RGB24:
979                 target_params.bpp = 3;
980                 if (other->pixel_format() == AV_PIX_FMT_RGBA64BE) {
981                         alpha_blend_onto_rgb24<uint16_t>(target_params, other_rgb_params, red, blue, byteswap, 256);
982                 } else {
983                         alpha_blend_onto_rgb24<uint8_t>(target_params, other_rgb_params, red, blue, pass, 1);
984                 }
985                 break;
986         case AV_PIX_FMT_BGRA:
987                 target_params.bpp = 4;
988                 if (other->pixel_format() == AV_PIX_FMT_RGBA64BE) {
989                         alpha_blend_onto_bgra<uint16_t>(target_params, other_rgb_params, red, blue, byteswap, 256);
990                 } else {
991                         alpha_blend_onto_bgra<uint8_t>(target_params, other_rgb_params, red, blue, pass, 1);
992                 }
993                 break;
994         case AV_PIX_FMT_RGBA:
995                 target_params.bpp = 4;
996                 if (other->pixel_format() == AV_PIX_FMT_RGBA64BE) {
997                         alpha_blend_onto_rgba<uint16_t>(target_params, other_rgb_params, red, blue, byteswap, 256);
998                 } else {
999                         alpha_blend_onto_rgba<uint8_t>(target_params, other_rgb_params, red, blue, pass, 1);
1000                 }
1001                 break;
1002         case AV_PIX_FMT_RGB48LE:
1003                 target_params.bpp = 6;
1004                 if (other->pixel_format() == AV_PIX_FMT_RGBA64BE) {
1005                         alpha_blend_onto_rgb48le<uint16_t>(target_params, other_rgb_params, red, blue, byteswap, 1);
1006                 } else {
1007                         alpha_blend_onto_rgb48le<uint8_t>(target_params, other_rgb_params, red, blue, pass, 256);
1008                 }
1009                 break;
1010         case AV_PIX_FMT_XYZ12LE:
1011                 target_params.bpp = 6;
1012                 if (other->pixel_format() == AV_PIX_FMT_RGBA64BE) {
1013                         alpha_blend_onto_xyz12le<uint16_t>(target_params, other_rgb_params, red, blue, byteswap, 256);
1014                 } else {
1015                         alpha_blend_onto_xyz12le<uint8_t>(target_params, other_rgb_params, red, blue, pass, 1);
1016                 }
1017                 break;
1018         case AV_PIX_FMT_YUV420P:
1019         {
1020                 auto yuv = other->convert_pixel_format (dcp::YUVToRGB::REC709, _pixel_format, Alignment::COMPACT, false);
1021                 other_yuv_params.data = yuv->data();
1022                 other_yuv_params.stride = yuv->stride();
1023                 other_yuv_params.alpha_data = other->data();
1024                 other_yuv_params.alpha_stride = other->stride();
1025                 alpha_blend_onto_yuv420p(target_params, other_yuv_params);
1026                 break;
1027         }
1028         case AV_PIX_FMT_YUV420P10:
1029         {
1030                 auto yuv = other->convert_pixel_format (dcp::YUVToRGB::REC709, _pixel_format, Alignment::COMPACT, false);
1031                 other_yuv_params.data = yuv->data();
1032                 other_yuv_params.stride = yuv->stride();
1033                 other_yuv_params.alpha_data = other->data();
1034                 other_yuv_params.alpha_stride = other->stride();
1035                 alpha_blend_onto_yuv420p10(target_params, other_yuv_params);
1036                 break;
1037         }
1038         case AV_PIX_FMT_YUV422P9LE:
1039         case AV_PIX_FMT_YUV422P10LE:
1040         {
1041                 auto yuv = other->convert_pixel_format (dcp::YUVToRGB::REC709, _pixel_format, Alignment::COMPACT, false);
1042                 other_yuv_params.data = yuv->data();
1043                 other_yuv_params.stride = yuv->stride();
1044                 alpha_blend_onto_yuv422p9or10le(target_params, other_yuv_params);
1045                 break;
1046         }
1047         default:
1048                 throw PixelFormatError ("alpha_blend()", _pixel_format);
1049         }
1050 }
1051
1052
1053 void
1054 Image::copy (shared_ptr<const Image> other, Position<int> position)
1055 {
1056         /* Only implemented for RGB24 onto RGB24 so far */
1057         DCPOMATIC_ASSERT (_pixel_format == AV_PIX_FMT_RGB24 && other->pixel_format() == AV_PIX_FMT_RGB24);
1058         DCPOMATIC_ASSERT (position.x >= 0 && position.y >= 0);
1059
1060         int const N = min (position.x + other->size().width, size().width) - position.x;
1061         for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
1062                 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
1063                 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
1064                 memcpy (tp, op, N * 3);
1065         }
1066 }
1067
1068
1069 void
1070 Image::read_from_socket (shared_ptr<Socket> socket)
1071 {
1072         for (int i = 0; i < planes(); ++i) {
1073                 uint8_t* p = data()[i];
1074                 int const lines = sample_size(i).height;
1075                 for (int y = 0; y < lines; ++y) {
1076                         socket->read (p, line_size()[i]);
1077                         p += stride()[i];
1078                 }
1079         }
1080 }
1081
1082
1083 void
1084 Image::write_to_socket (shared_ptr<Socket> socket) const
1085 {
1086         for (int i = 0; i < planes(); ++i) {
1087                 uint8_t* p = data()[i];
1088                 int const lines = sample_size(i).height;
1089                 for (int y = 0; y < lines; ++y) {
1090                         socket->write (p, line_size()[i]);
1091                         p += stride()[i];
1092                 }
1093         }
1094 }
1095
1096
1097 float
1098 Image::bytes_per_pixel (int c) const
1099 {
1100         auto d = av_pix_fmt_desc_get(_pixel_format);
1101         if (!d) {
1102                 throw PixelFormatError ("bytes_per_pixel()", _pixel_format);
1103         }
1104
1105         if (c >= planes()) {
1106                 return 0;
1107         }
1108
1109         float bpp[4] = { 0, 0, 0, 0 };
1110
1111 #ifdef DCPOMATIC_HAVE_AVCOMPONENTDESCRIPTOR_DEPTH_MINUS1
1112         bpp[0] = floor ((d->comp[0].depth_minus1 + 8) / 8);
1113         if (d->nb_components > 1) {
1114                 bpp[1] = floor ((d->comp[1].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
1115         }
1116         if (d->nb_components > 2) {
1117                 bpp[2] = floor ((d->comp[2].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
1118         }
1119         if (d->nb_components > 3) {
1120                 bpp[3] = floor ((d->comp[3].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
1121         }
1122 #else
1123         bpp[0] = floor ((d->comp[0].depth + 7) / 8);
1124         if (d->nb_components > 1) {
1125                 bpp[1] = floor ((d->comp[1].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
1126         }
1127         if (d->nb_components > 2) {
1128                 bpp[2] = floor ((d->comp[2].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
1129         }
1130         if (d->nb_components > 3) {
1131                 bpp[3] = floor ((d->comp[3].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
1132         }
1133 #endif
1134
1135         if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
1136                 /* Not planar; sum them up */
1137                 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
1138         }
1139
1140         return bpp[c];
1141 }
1142
1143
1144 /** Construct a Image of a given size and format, allocating memory
1145  *  as required.
1146  *
1147  *  @param p Pixel format.
1148  *  @param s Size in pixels.
1149  *  @param alignment PADDED to make each row of this image aligned to a ALIGNMENT-byte boundary, otherwise COMPACT.
1150  */
1151 Image::Image (AVPixelFormat p, dcp::Size s, Alignment alignment)
1152         : _size (s)
1153         , _pixel_format (p)
1154         , _alignment (alignment)
1155 {
1156         allocate ();
1157 }
1158
1159
1160 void
1161 Image::allocate ()
1162 {
1163         _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
1164         _data[0] = _data[1] = _data[2] = _data[3] = 0;
1165
1166         _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
1167         _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
1168
1169         _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
1170         _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
1171
1172         auto stride_round_up = [](int stride, int t) {
1173                 int const a = stride + (t - 1);
1174                 return a - (a % t);
1175         };
1176
1177         for (int i = 0; i < planes(); ++i) {
1178                 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
1179                 _stride[i] = stride_round_up (_line_size[i], _alignment == Alignment::PADDED ? ALIGNMENT : 1);
1180
1181                 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
1182                    uses a 16-byte fetch to read three bytes (R/G/B) of image data.
1183                    Hence on the last pixel of the last line it reads over the end of
1184                    the actual data by 1 byte.  If the width of an image is a multiple
1185                    of the stride alignment there will be no padding at the end of image lines.
1186                    OS X crashes on this illegal read, though other operating systems don't
1187                    seem to mind.  The nasty + 1 in this malloc makes sure there is always a byte
1188                    for that instruction to read safely.
1189
1190                    Further to the above, valgrind is now telling me that ff_rgb24ToY_ssse3
1191                    over-reads by more then _avx.  I can't follow the code to work out how much,
1192                    so I'll just over-allocate by ALIGNMENT bytes and have done with it.  Empirical
1193                    testing suggests that it works.
1194
1195                    In addition to these concerns, we may read/write as much as a whole extra line
1196                    at the end of each plane in cases where we are messing with offsets in order to
1197                    do pad or crop.  To solve this we over-allocate by an extra _stride[i] bytes.
1198
1199                    As an example: we may write to images starting at an offset so we get some padding.
1200                    Hence we want to write in the following pattern:
1201
1202                    block start   write start                                  line end
1203                    |..(padding)..|<------line-size------------->|..(padding)..|
1204                    |..(padding)..|<------line-size------------->|..(padding)..|
1205                    |..(padding)..|<------line-size------------->|..(padding)..|
1206
1207                    where line-size is of the smaller (inter_size) image and the full padded line length is that of
1208                    out_size.  To get things to work we have to tell FFmpeg that the stride is that of out_size.
1209                    However some parts of FFmpeg (notably rgb48Toxyz12 in swscale.c) process data for the full
1210                    specified *stride*.  This does not matter until we get to the last line:
1211
1212                    block start   write start                                  line end
1213                    |..(padding)..|<------line-size------------->|XXXwrittenXXX|
1214                    |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXX|
1215                    |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXXXXXwrittenXXX
1216                                                                                ^^^^ out of bounds
1217                 */
1218                 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * (sample_size(i).height + 1) + ALIGNMENT);
1219 #if HAVE_VALGRIND_MEMCHECK_H
1220                 /* The data between the end of the line size and the stride is undefined but processed by
1221                    libswscale, causing lots of valgrind errors.  Mark it all defined to quell these errors.
1222                 */
1223                 VALGRIND_MAKE_MEM_DEFINED (_data[i], _stride[i] * (sample_size(i).height + 1) + ALIGNMENT);
1224 #endif
1225         }
1226 }
1227
1228
1229 Image::Image (Image const & other)
1230         : std::enable_shared_from_this<Image>(other)
1231         , _size (other._size)
1232         , _pixel_format (other._pixel_format)
1233         , _alignment (other._alignment)
1234 {
1235         allocate ();
1236
1237         for (int i = 0; i < planes(); ++i) {
1238                 uint8_t* p = _data[i];
1239                 uint8_t* q = other._data[i];
1240                 int const lines = sample_size(i).height;
1241                 for (int j = 0; j < lines; ++j) {
1242                         memcpy (p, q, _line_size[i]);
1243                         p += stride()[i];
1244                         q += other.stride()[i];
1245                 }
1246         }
1247 }
1248
1249
1250 Image::Image (AVFrame const * frame, Alignment alignment)
1251         : _size (frame->width, frame->height)
1252         , _pixel_format (static_cast<AVPixelFormat>(frame->format))
1253         , _alignment (alignment)
1254 {
1255         DCPOMATIC_ASSERT (_pixel_format != AV_PIX_FMT_NONE);
1256
1257         allocate ();
1258
1259         for (int i = 0; i < planes(); ++i) {
1260                 uint8_t* p = _data[i];
1261                 uint8_t* q = frame->data[i];
1262                 int const lines = sample_size(i).height;
1263                 for (int j = 0; j < lines; ++j) {
1264                         memcpy (p, q, _line_size[i]);
1265                         p += stride()[i];
1266                         /* AVFrame's linesize is what we call `stride' */
1267                         q += frame->linesize[i];
1268                 }
1269         }
1270 }
1271
1272
1273 Image::Image (shared_ptr<const Image> other, Alignment alignment)
1274         : _size (other->_size)
1275         , _pixel_format (other->_pixel_format)
1276         , _alignment (alignment)
1277 {
1278         allocate ();
1279
1280         for (int i = 0; i < planes(); ++i) {
1281                 DCPOMATIC_ASSERT (line_size()[i] == other->line_size()[i]);
1282                 uint8_t* p = _data[i];
1283                 uint8_t* q = other->data()[i];
1284                 int const lines = sample_size(i).height;
1285                 for (int j = 0; j < lines; ++j) {
1286                         memcpy (p, q, line_size()[i]);
1287                         p += stride()[i];
1288                         q += other->stride()[i];
1289                 }
1290         }
1291 }
1292
1293
1294 Image&
1295 Image::operator= (Image const & other)
1296 {
1297         if (this == &other) {
1298                 return *this;
1299         }
1300
1301         Image tmp (other);
1302         swap (tmp);
1303         return *this;
1304 }
1305
1306
1307 void
1308 Image::swap (Image & other)
1309 {
1310         std::swap (_size, other._size);
1311         std::swap (_pixel_format, other._pixel_format);
1312
1313         for (int i = 0; i < 4; ++i) {
1314                 std::swap (_data[i], other._data[i]);
1315                 std::swap (_line_size[i], other._line_size[i]);
1316                 std::swap (_stride[i], other._stride[i]);
1317         }
1318
1319         std::swap (_alignment, other._alignment);
1320 }
1321
1322
1323 Image::~Image ()
1324 {
1325         for (int i = 0; i < planes(); ++i) {
1326                 av_free (_data[i]);
1327         }
1328
1329         av_free (_data);
1330         av_free (_line_size);
1331         av_free (_stride);
1332 }
1333
1334
1335 uint8_t * const *
1336 Image::data () const
1337 {
1338         return _data;
1339 }
1340
1341
1342 int const *
1343 Image::line_size () const
1344 {
1345         return _line_size;
1346 }
1347
1348
1349 int const *
1350 Image::stride () const
1351 {
1352         return _stride;
1353 }
1354
1355
1356 dcp::Size
1357 Image::size () const
1358 {
1359         return _size;
1360 }
1361
1362
1363 Image::Alignment
1364 Image::alignment () const
1365 {
1366         return _alignment;
1367 }
1368
1369
1370 PositionImage
1371 merge (list<PositionImage> images, Image::Alignment alignment)
1372 {
1373         if (images.empty ()) {
1374                 return {};
1375         }
1376
1377         if (images.size() == 1) {
1378                 images.front().image = Image::ensure_alignment(images.front().image, alignment);
1379                 return images.front();
1380         }
1381
1382         dcpomatic::Rect<int> all (images.front().position, images.front().image->size().width, images.front().image->size().height);
1383         for (auto const& i: images) {
1384                 all.extend (dcpomatic::Rect<int>(i.position, i.image->size().width, i.image->size().height));
1385         }
1386
1387         auto merged = make_shared<Image>(images.front().image->pixel_format(), dcp::Size(all.width, all.height), alignment);
1388         merged->make_transparent ();
1389         for (auto const& i: images) {
1390                 merged->alpha_blend (i.image, i.position - all.position());
1391         }
1392
1393         return PositionImage (merged, all.position ());
1394 }
1395
1396
1397 bool
1398 operator== (Image const & a, Image const & b)
1399 {
1400         if (a.planes() != b.planes() || a.pixel_format() != b.pixel_format() || a.alignment() != b.alignment()) {
1401                 return false;
1402         }
1403
1404         for (int c = 0; c < a.planes(); ++c) {
1405                 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]) {
1406                         return false;
1407                 }
1408
1409                 uint8_t* p = a.data()[c];
1410                 uint8_t* q = b.data()[c];
1411                 int const lines = a.sample_size(c).height;
1412                 for (int y = 0; y < lines; ++y) {
1413                         if (memcmp (p, q, a.line_size()[c]) != 0) {
1414                                 return false;
1415                         }
1416
1417                         p += a.stride()[c];
1418                         q += b.stride()[c];
1419                 }
1420         }
1421
1422         return true;
1423 }
1424
1425
1426 /** Fade the image.
1427  *  @param f Amount to fade by; 0 is black, 1 is no fade.
1428  */
1429 void
1430 Image::fade (float f)
1431 {
1432         /* U/V black value for 8-bit colour */
1433         static int const eight_bit_uv =    (1 << 7) - 1;
1434         /* U/V black value for 10-bit colour */
1435         static uint16_t const ten_bit_uv = (1 << 9) - 1;
1436
1437         switch (_pixel_format) {
1438         case AV_PIX_FMT_YUV420P:
1439         {
1440                 /* Y */
1441                 uint8_t* p = data()[0];
1442                 int const lines = sample_size(0).height;
1443                 for (int y = 0; y < lines; ++y) {
1444                         uint8_t* q = p;
1445                         for (int x = 0; x < line_size()[0]; ++x) {
1446                                 *q = int(float(*q) * f);
1447                                 ++q;
1448                         }
1449                         p += stride()[0];
1450                 }
1451
1452                 /* U, V */
1453                 for (int c = 1; c < 3; ++c) {
1454                         uint8_t* p = data()[c];
1455                         int const lines = sample_size(c).height;
1456                         for (int y = 0; y < lines; ++y) {
1457                                 uint8_t* q = p;
1458                                 for (int x = 0; x < line_size()[c]; ++x) {
1459                                         *q = eight_bit_uv + int((int(*q) - eight_bit_uv) * f);
1460                                         ++q;
1461                                 }
1462                                 p += stride()[c];
1463                         }
1464                 }
1465
1466                 break;
1467         }
1468
1469         case AV_PIX_FMT_RGB24:
1470         {
1471                 /* 8-bit */
1472                 uint8_t* p = data()[0];
1473                 int const lines = sample_size(0).height;
1474                 for (int y = 0; y < lines; ++y) {
1475                         uint8_t* q = p;
1476                         for (int x = 0; x < line_size()[0]; ++x) {
1477                                 *q = int (float (*q) * f);
1478                                 ++q;
1479                         }
1480                         p += stride()[0];
1481                 }
1482                 break;
1483         }
1484
1485         case AV_PIX_FMT_XYZ12LE:
1486         case AV_PIX_FMT_RGB48LE:
1487                 /* 16-bit little-endian */
1488                 for (int c = 0; c < 3; ++c) {
1489                         int const stride_pixels = stride()[c] / 2;
1490                         int const line_size_pixels = line_size()[c] / 2;
1491                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1492                         int const lines = sample_size(c).height;
1493                         for (int y = 0; y < lines; ++y) {
1494                                 uint16_t* q = p;
1495                                 for (int x = 0; x < line_size_pixels; ++x) {
1496                                         *q = int (float (*q) * f);
1497                                         ++q;
1498                                 }
1499                                 p += stride_pixels;
1500                         }
1501                 }
1502                 break;
1503
1504         case AV_PIX_FMT_YUV422P10LE:
1505         {
1506                 /* Y */
1507                 {
1508                         int const stride_pixels = stride()[0] / 2;
1509                         int const line_size_pixels = line_size()[0] / 2;
1510                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[0]);
1511                         int const lines = sample_size(0).height;
1512                         for (int y = 0; y < lines; ++y) {
1513                                 uint16_t* q = p;
1514                                 for (int x = 0; x < line_size_pixels; ++x) {
1515                                         *q = int(float(*q) * f);
1516                                         ++q;
1517                                 }
1518                                 p += stride_pixels;
1519                         }
1520                 }
1521
1522                 /* U, V */
1523                 for (int c = 1; c < 3; ++c) {
1524                         int const stride_pixels = stride()[c] / 2;
1525                         int const line_size_pixels = line_size()[c] / 2;
1526                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1527                         int const lines = sample_size(c).height;
1528                         for (int y = 0; y < lines; ++y) {
1529                                 uint16_t* q = p;
1530                                 for (int x = 0; x < line_size_pixels; ++x) {
1531                                         *q = ten_bit_uv + int((int(*q) - ten_bit_uv) * f);
1532                                         ++q;
1533                                 }
1534                                 p += stride_pixels;
1535                         }
1536                 }
1537                 break;
1538
1539         }
1540
1541         default:
1542                 throw PixelFormatError ("fade()", _pixel_format);
1543         }
1544 }
1545
1546
1547 shared_ptr<const Image>
1548 Image::ensure_alignment (shared_ptr<const Image> image, Image::Alignment alignment)
1549 {
1550         if (image->alignment() == alignment) {
1551                 return image;
1552         }
1553
1554         return make_shared<Image>(image, alignment);
1555 }
1556
1557
1558 size_t
1559 Image::memory_used () const
1560 {
1561         size_t m = 0;
1562         for (int i = 0; i < planes(); ++i) {
1563                 m += _stride[i] * sample_size(i).height;
1564         }
1565         return m;
1566 }
1567
1568
1569 void
1570 Image::video_range_to_full_range ()
1571 {
1572         switch (_pixel_format) {
1573         case AV_PIX_FMT_RGB24:
1574         {
1575                 float const factor = 256.0 / 219.0;
1576                 uint8_t* p = data()[0];
1577                 int const lines = sample_size(0).height;
1578                 for (int y = 0; y < lines; ++y) {
1579                         uint8_t* q = p;
1580                         for (int x = 0; x < line_size()[0]; ++x) {
1581                                 *q = clamp(lrintf((*q - 16) * factor), 0L, 255L);
1582                                 ++q;
1583                         }
1584                         p += stride()[0];
1585                 }
1586                 break;
1587         }
1588         case AV_PIX_FMT_RGB48LE:
1589         {
1590                 float const factor = 65536.0 / 56064.0;
1591                 uint16_t* p = reinterpret_cast<uint16_t*>(data()[0]);
1592                 int const lines = sample_size(0).height;
1593                 for (int y = 0; y < lines; ++y) {
1594                         uint16_t* q = p;
1595                         int const line_size_pixels = line_size()[0] / 2;
1596                         for (int x = 0; x < line_size_pixels; ++x) {
1597                                 *q = clamp(lrintf((*q - 4096) * factor), 0L, 65535L);
1598                                 ++q;
1599                         }
1600                         p += stride()[0] / 2;
1601                 }
1602                 break;
1603         }
1604         case AV_PIX_FMT_GBRP12LE:
1605         {
1606                 float const factor = 4096.0 / 3504.0;
1607                 for (int c = 0; c < 3; ++c) {
1608                         uint16_t* p = reinterpret_cast<uint16_t*>(data()[c]);
1609                         int const lines = sample_size(c).height;
1610                         for (int y = 0; y < lines; ++y) {
1611                                 uint16_t* q = p;
1612                                 int const line_size_pixels = line_size()[c] / 2;
1613                                 for (int x = 0; x < line_size_pixels; ++x) {
1614                                         *q = clamp(lrintf((*q - 256) * factor), 0L, 4095L);
1615                                         ++q;
1616                                 }
1617                         }
1618                 }
1619                 break;
1620         }
1621         default:
1622                 throw PixelFormatError ("video_range_to_full_range()", _pixel_format);
1623         }
1624 }
1625