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