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