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