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