Use EnumIndexedVector in Image.
[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
244         /* The 3rd parameter here is:
245            0 -> source range MPEG (i.e. "video", 16-235)
246            1 -> source range JPEG (i.e. "full", 0-255)
247            And the 5th:
248            0 -> destination range MPEG (i.e. "video", 16-235)
249            1 -> destination range JPEG (i.e. "full", 0-255)
250
251            But remember: sws_setColorspaceDetails ignores these
252            parameters unless the both source and destination images
253            are isYUV or isGray.  (If either is not, it uses video range).
254         */
255         sws_setColorspaceDetails (
256                 scale_context,
257                 sws_getCoefficients(lut[yuv_to_rgb]), video_range == VideoRange::VIDEO ? 0 : 1,
258                 sws_getCoefficients(lut[yuv_to_rgb]), out_video_range == VideoRange::VIDEO ? 0 : 1,
259                 0, 1 << 16, 1 << 16
260                 );
261
262         /* Prepare input data pointers with crop */
263         uint8_t* scale_in_data[planes()];
264         for (int c = 0; c < planes(); ++c) {
265                 int const x = lrintf(bytes_per_pixel(c) * corrected_crop.left);
266                 scale_in_data[c] = data()[c] + x + stride()[c] * (corrected_crop.top / vertical_factor(c));
267         }
268
269         auto out_desc = av_pix_fmt_desc_get (out_format);
270         if (!out_desc) {
271                 throw PixelFormatError ("crop_scale_window()", out_format);
272         }
273
274         /* Corner of the image within out_size */
275         Position<int> const corner (
276                 round_width_for_subsampling((out_size.width - inter_size.width) / 2, out_desc),
277                 round_height_for_subsampling((out_size.height - inter_size.height) / 2, out_desc)
278                 );
279
280         uint8_t* scale_out_data[out->planes()];
281         for (int c = 0; c < out->planes(); ++c) {
282                 int const x = lrintf(out->bytes_per_pixel(c) * corner.x);
283                 scale_out_data[c] = out->data()[c] + x + out->stride()[c] * (corner.y / out->vertical_factor(c));
284         }
285
286         sws_scale (
287                 scale_context,
288                 scale_in_data, stride(),
289                 0, cropped_size.height,
290                 scale_out_data, out->stride()
291                 );
292
293         sws_freeContext (scale_context);
294
295         /* There are some cases where there will be unwanted image data left in the image at this point:
296          *
297          * 1. When we are cropping without any scaling or pixel format conversion.
298          * 2. When we are scaling to certain sizes and placing the result into a larger
299          *    black frame.
300          *
301          * Clear out the sides of the image to take care of those cases.
302          */
303         auto const pad = (out_size.width - inter_size.width) / 2;
304         out->make_part_black(0, pad);
305         out->make_part_black(corner.x + inter_size.width, pad);
306
307         if (
308                 video_range == VideoRange::VIDEO &&
309                 out_video_range == VideoRange::FULL &&
310                 av_pix_fmt_desc_get(_pixel_format)->flags & AV_PIX_FMT_FLAG_RGB
311            ) {
312                 /* libswscale will not convert video range for RGB sources, so we have to do it ourselves */
313                 out->video_range_to_full_range ();
314         }
315
316         return out;
317 }
318
319
320 shared_ptr<Image>
321 Image::convert_pixel_format (dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, Alignment out_alignment, bool fast) const
322 {
323         return scale(size(), yuv_to_rgb, out_format, out_alignment, fast);
324 }
325
326
327 /** @param out_size Size to scale to.
328  *  @param yuv_to_rgb YUVToRGB transform transform to use, if required.
329  *  @param out_format Output pixel format.
330  *  @param out_aligment Output alignment.
331  *  @param fast Try to be fast at the possible expense of quality; at present this means using
332  *  fast bilinear rather than bicubic scaling.
333  */
334 shared_ptr<Image>
335 Image::scale (dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, Alignment out_alignment, bool fast) const
336 {
337         /* Empirical testing suggests that sws_scale() will crash if
338            the input image alignment is not PADDED.
339         */
340         DCPOMATIC_ASSERT (alignment() == Alignment::PADDED);
341
342         auto scaled = make_shared<Image>(out_format, out_size, out_alignment);
343         auto scale_context = sws_getContext (
344                 size().width, size().height, pixel_format(),
345                 out_size.width, out_size.height, out_format,
346                 (fast ? SWS_FAST_BILINEAR : SWS_BICUBIC) | SWS_ACCURATE_RND, 0, 0, 0
347                 );
348
349         DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUVToRGB::COUNT);
350         EnumIndexedVector<int, dcp::YUVToRGB> lut;
351         lut[dcp::YUVToRGB::REC601] = SWS_CS_ITU601;
352         lut[dcp::YUVToRGB::REC709] = SWS_CS_ITU709;
353
354         /* The 3rd parameter here is:
355            0 -> source range MPEG (i.e. "video", 16-235)
356            1 -> source range JPEG (i.e. "full", 0-255)
357            And the 5th:
358            0 -> destination range MPEG (i.e. "video", 16-235)
359            1 -> destination range JPEG (i.e. "full", 0-255)
360
361            But remember: sws_setColorspaceDetails ignores these
362            parameters unless the corresponding image isYUV or isGray.
363            (If it's neither, it uses video range).
364         */
365         sws_setColorspaceDetails (
366                 scale_context,
367                 sws_getCoefficients(lut[yuv_to_rgb]), 0,
368                 sws_getCoefficients(lut[yuv_to_rgb]), 0,
369                 0, 1 << 16, 1 << 16
370                 );
371
372         sws_scale (
373                 scale_context,
374                 data(), stride(),
375                 0, size().height,
376                 scaled->data(), scaled->stride()
377                 );
378
379         sws_freeContext (scale_context);
380
381         return scaled;
382 }
383
384
385 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
386 void
387 Image::yuv_16_black (uint16_t v, bool alpha)
388 {
389         memset (data()[0], 0, sample_size(0).height * stride()[0]);
390         for (int i = 1; i < 3; ++i) {
391                 auto p = reinterpret_cast<int16_t*> (data()[i]);
392                 int const lines = sample_size(i).height;
393                 for (int y = 0; y < lines; ++y) {
394                         /* We divide by 2 here because we are writing 2 bytes at a time */
395                         for (int x = 0; x < line_size()[i] / 2; ++x) {
396                                 p[x] = v;
397                         }
398                         p += stride()[i] / 2;
399                 }
400         }
401
402         if (alpha) {
403                 memset (data()[3], 0, sample_size(3).height * stride()[3]);
404         }
405 }
406
407
408 uint16_t
409 Image::swap_16 (uint16_t v)
410 {
411         return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
412 }
413
414
415 void
416 Image::make_part_black (int const start, int const width)
417 {
418         auto y_part = [&]() {
419                 int const bpp = bytes_per_pixel(0);
420                 int const h = sample_size(0).height;
421                 int const s = stride()[0];
422                 auto p = data()[0];
423                 for (int y = 0; y < h; ++y) {
424                         memset (p + start * bpp, 0, width * bpp);
425                         p += s;
426                 }
427         };
428
429         switch (_pixel_format) {
430         case AV_PIX_FMT_RGB24:
431         case AV_PIX_FMT_ARGB:
432         case AV_PIX_FMT_RGBA:
433         case AV_PIX_FMT_ABGR:
434         case AV_PIX_FMT_BGRA:
435         case AV_PIX_FMT_RGB555LE:
436         case AV_PIX_FMT_RGB48LE:
437         case AV_PIX_FMT_RGB48BE:
438         case AV_PIX_FMT_XYZ12LE:
439         {
440                 int const h = sample_size(0).height;
441                 int const bpp = bytes_per_pixel(0);
442                 int const s = stride()[0];
443                 uint8_t* p = data()[0];
444                 for (int y = 0; y < h; y++) {
445                         memset (p + start * bpp, 0, width * bpp);
446                         p += s;
447                 }
448                 break;
449         }
450         case AV_PIX_FMT_YUV420P:
451         {
452                 y_part ();
453                 for (int i = 1; i < 3; ++i) {
454                         auto p = data()[i];
455                         int const h = sample_size(i).height;
456                         for (int y = 0; y < h; ++y) {
457                                 for (int x = start / 2; x < (start + width) / 2; ++x) {
458                                         p[x] = eight_bit_uv;
459                                 }
460                                 p += stride()[i];
461                         }
462                 }
463                 break;
464         }
465         case AV_PIX_FMT_YUV422P10LE:
466         {
467                 y_part ();
468                 for (int i = 1; i < 3; ++i) {
469                         auto p = reinterpret_cast<int16_t*>(data()[i]);
470                         int const h = sample_size(i).height;
471                         for (int y = 0; y < h; ++y) {
472                                 for (int x = start / 2; x < (start + width) / 2; ++x) {
473                                         p[x] = ten_bit_uv;
474                                 }
475                                 p += stride()[i] / 2;
476                         }
477                 }
478                 break;
479         }
480         case AV_PIX_FMT_YUV444P10LE:
481         {
482                 y_part();
483                 for (int i = 1; i < 3; ++i) {
484                         auto p = reinterpret_cast<int16_t*>(data()[i]);
485                         int const h = sample_size(i).height;
486                         for (int y = 0; y < h; ++y) {
487                                 for (int x = start; x < (start + width); ++x) {
488                                         p[x] = ten_bit_uv;
489                                 }
490                                 p += stride()[i] / 2;
491                         }
492                 }
493                 break;
494         }
495         default:
496                 throw PixelFormatError ("make_part_black()", _pixel_format);
497         }
498 }
499
500
501 void
502 Image::make_black ()
503 {
504         switch (_pixel_format) {
505         case AV_PIX_FMT_YUV420P:
506         case AV_PIX_FMT_YUV422P:
507         case AV_PIX_FMT_YUV444P:
508         case AV_PIX_FMT_YUV411P:
509                 memset (data()[0], 0, sample_size(0).height * stride()[0]);
510                 memset (data()[1], eight_bit_uv, sample_size(1).height * stride()[1]);
511                 memset (data()[2], eight_bit_uv, sample_size(2).height * stride()[2]);
512                 break;
513
514         case AV_PIX_FMT_YUVJ420P:
515         case AV_PIX_FMT_YUVJ422P:
516         case AV_PIX_FMT_YUVJ444P:
517                 memset (data()[0], 0, sample_size(0).height * stride()[0]);
518                 memset (data()[1], eight_bit_uv + 1, sample_size(1).height * stride()[1]);
519                 memset (data()[2], eight_bit_uv + 1, sample_size(2).height * stride()[2]);
520                 break;
521
522         case AV_PIX_FMT_YUV422P9LE:
523         case AV_PIX_FMT_YUV444P9LE:
524                 yuv_16_black (nine_bit_uv, false);
525                 break;
526
527         case AV_PIX_FMT_YUV422P9BE:
528         case AV_PIX_FMT_YUV444P9BE:
529                 yuv_16_black (swap_16 (nine_bit_uv), false);
530                 break;
531
532         case AV_PIX_FMT_YUV422P10LE:
533         case AV_PIX_FMT_YUV444P10LE:
534                 yuv_16_black (ten_bit_uv, false);
535                 break;
536
537         case AV_PIX_FMT_YUV422P16LE:
538         case AV_PIX_FMT_YUV444P16LE:
539                 yuv_16_black (sixteen_bit_uv, false);
540                 break;
541
542         case AV_PIX_FMT_YUV444P10BE:
543         case AV_PIX_FMT_YUV422P10BE:
544                 yuv_16_black (swap_16 (ten_bit_uv), false);
545                 break;
546
547         case AV_PIX_FMT_YUVA420P9BE:
548         case AV_PIX_FMT_YUVA422P9BE:
549         case AV_PIX_FMT_YUVA444P9BE:
550                 yuv_16_black (swap_16 (nine_bit_uv), true);
551                 break;
552
553         case AV_PIX_FMT_YUVA420P9LE:
554         case AV_PIX_FMT_YUVA422P9LE:
555         case AV_PIX_FMT_YUVA444P9LE:
556                 yuv_16_black (nine_bit_uv, true);
557                 break;
558
559         case AV_PIX_FMT_YUVA420P10BE:
560         case AV_PIX_FMT_YUVA422P10BE:
561         case AV_PIX_FMT_YUVA444P10BE:
562                 yuv_16_black (swap_16 (ten_bit_uv), true);
563                 break;
564
565         case AV_PIX_FMT_YUVA420P10LE:
566         case AV_PIX_FMT_YUVA422P10LE:
567         case AV_PIX_FMT_YUVA444P10LE:
568                 yuv_16_black (ten_bit_uv, true);
569                 break;
570
571         case AV_PIX_FMT_YUVA420P16BE:
572         case AV_PIX_FMT_YUVA422P16BE:
573         case AV_PIX_FMT_YUVA444P16BE:
574                 yuv_16_black (swap_16 (sixteen_bit_uv), true);
575                 break;
576
577         case AV_PIX_FMT_YUVA420P16LE:
578         case AV_PIX_FMT_YUVA422P16LE:
579         case AV_PIX_FMT_YUVA444P16LE:
580                 yuv_16_black (sixteen_bit_uv, true);
581                 break;
582
583         case AV_PIX_FMT_RGB24:
584         case AV_PIX_FMT_ARGB:
585         case AV_PIX_FMT_RGBA:
586         case AV_PIX_FMT_ABGR:
587         case AV_PIX_FMT_BGRA:
588         case AV_PIX_FMT_RGB555LE:
589         case AV_PIX_FMT_RGB48LE:
590         case AV_PIX_FMT_RGB48BE:
591         case AV_PIX_FMT_XYZ12LE:
592                 memset (data()[0], 0, sample_size(0).height * stride()[0]);
593                 break;
594
595         case AV_PIX_FMT_UYVY422:
596         {
597                 int const Y = sample_size(0).height;
598                 int const X = line_size()[0];
599                 uint8_t* p = data()[0];
600                 for (int y = 0; y < Y; ++y) {
601                         for (int x = 0; x < X / 4; ++x) {
602                                 *p++ = eight_bit_uv; // Cb
603                                 *p++ = 0;            // Y0
604                                 *p++ = eight_bit_uv; // Cr
605                                 *p++ = 0;            // Y1
606                         }
607                 }
608                 break;
609         }
610
611         default:
612                 throw PixelFormatError ("make_black()", _pixel_format);
613         }
614 }
615
616
617 void
618 Image::make_transparent ()
619 {
620         if (_pixel_format != AV_PIX_FMT_BGRA && _pixel_format != AV_PIX_FMT_RGBA) {
621                 throw PixelFormatError ("make_transparent()", _pixel_format);
622         }
623
624         memset (data()[0], 0, sample_size(0).height * stride()[0]);
625 }
626
627
628 void
629 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
630 {
631         /* We're blending RGBA or BGRA images */
632         DCPOMATIC_ASSERT (other->pixel_format() == AV_PIX_FMT_BGRA || other->pixel_format() == AV_PIX_FMT_RGBA);
633         int const blue = other->pixel_format() == AV_PIX_FMT_BGRA ? 0 : 2;
634         int const red = other->pixel_format() == AV_PIX_FMT_BGRA ? 2 : 0;
635
636         int const other_bpp = 4;
637
638         int start_tx = position.x;
639         int start_ox = 0;
640
641         if (start_tx < 0) {
642                 start_ox = -start_tx;
643                 start_tx = 0;
644         }
645
646         int start_ty = position.y;
647         int start_oy = 0;
648
649         if (start_ty < 0) {
650                 start_oy = -start_ty;
651                 start_ty = 0;
652         }
653
654         switch (_pixel_format) {
655         case AV_PIX_FMT_RGB24:
656         {
657                 /* Going onto RGB24.  First byte is red, second green, third blue */
658                 int const this_bpp = 3;
659                 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
660                         uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
661                         uint8_t* op = other->data()[0] + oy * other->stride()[0];
662                         for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
663                                 float const alpha = float (op[3]) / 255;
664                                 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
665                                 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
666                                 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
667
668                                 tp += this_bpp;
669                                 op += other_bpp;
670                         }
671                 }
672                 break;
673         }
674         case AV_PIX_FMT_BGRA:
675         {
676                 int const this_bpp = 4;
677                 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
678                         uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
679                         uint8_t* op = other->data()[0] + oy * other->stride()[0];
680                         for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
681                                 float const alpha = float (op[3]) / 255;
682                                 tp[0] = op[blue] * alpha + tp[0] * (1 - alpha);
683                                 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
684                                 tp[2] = op[red] * alpha + tp[2] * (1 - alpha);
685                                 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
686
687                                 tp += this_bpp;
688                                 op += other_bpp;
689                         }
690                 }
691                 break;
692         }
693         case AV_PIX_FMT_RGBA:
694         {
695                 int const this_bpp = 4;
696                 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
697                         uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
698                         uint8_t* op = other->data()[0] + oy * other->stride()[0];
699                         for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
700                                 float const alpha = float (op[3]) / 255;
701                                 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
702                                 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
703                                 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
704                                 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
705
706                                 tp += this_bpp;
707                                 op += other_bpp;
708                         }
709                 }
710                 break;
711         }
712         case AV_PIX_FMT_RGB48LE:
713         {
714                 int const this_bpp = 6;
715                 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
716                         uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
717                         uint8_t* op = other->data()[0] + oy * other->stride()[0];
718                         for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
719                                 float const alpha = float (op[3]) / 255;
720                                 /* Blend high bytes */
721                                 tp[1] = op[red] * alpha + tp[1] * (1 - alpha);
722                                 tp[3] = op[1] * alpha + tp[3] * (1 - alpha);
723                                 tp[5] = op[blue] * alpha + tp[5] * (1 - alpha);
724
725                                 tp += this_bpp;
726                                 op += other_bpp;
727                         }
728                 }
729                 break;
730         }
731         case AV_PIX_FMT_XYZ12LE:
732         {
733                 auto conv = dcp::ColourConversion::srgb_to_xyz();
734                 double fast_matrix[9];
735                 dcp::combined_rgb_to_xyz (conv, fast_matrix);
736                 auto lut_in = conv.in()->lut(0, 1, 8, false);
737                 auto lut_out = conv.out()->lut(0, 1, 16, true);
738                 int const this_bpp = 6;
739                 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
740                         uint16_t* tp = reinterpret_cast<uint16_t*> (data()[0] + ty * stride()[0] + start_tx * this_bpp);
741                         uint8_t* op = other->data()[0] + oy * other->stride()[0];
742                         for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
743                                 float const alpha = float (op[3]) / 255;
744
745                                 /* Convert sRGB to XYZ; op is BGRA.  First, input gamma LUT */
746                                 double const r = lut_in[op[red]];
747                                 double const g = lut_in[op[1]];
748                                 double const b = lut_in[op[blue]];
749
750                                 /* RGB to XYZ, including Bradford transform and DCI companding */
751                                 double const x = max(0.0, min(1.0, r * fast_matrix[0] + g * fast_matrix[1] + b * fast_matrix[2]));
752                                 double const y = max(0.0, min(1.0, r * fast_matrix[3] + g * fast_matrix[4] + b * fast_matrix[5]));
753                                 double const z = max(0.0, min(1.0, r * fast_matrix[6] + g * fast_matrix[7] + b * fast_matrix[8]));
754
755                                 /* Out gamma LUT and blend */
756                                 tp[0] = lrint(lut_out[lrint(x * 65535)] * 65535) * alpha + tp[0] * (1 - alpha);
757                                 tp[1] = lrint(lut_out[lrint(y * 65535)] * 65535) * alpha + tp[1] * (1 - alpha);
758                                 tp[2] = lrint(lut_out[lrint(z * 65535)] * 65535) * alpha + tp[2] * (1 - alpha);
759
760                                 tp += this_bpp / 2;
761                                 op += other_bpp;
762                         }
763                 }
764                 break;
765         }
766         case AV_PIX_FMT_YUV420P:
767         {
768                 auto yuv = other->convert_pixel_format (dcp::YUVToRGB::REC709, _pixel_format, Alignment::COMPACT, false);
769                 dcp::Size const ts = size();
770                 dcp::Size const os = yuv->size();
771                 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
772                         int const hty = ty / 2;
773                         int const hoy = oy / 2;
774                         uint8_t* tY = data()[0] + (ty * stride()[0]) + start_tx;
775                         uint8_t* tU = data()[1] + (hty * stride()[1]) + start_tx / 2;
776                         uint8_t* tV = data()[2] + (hty * stride()[2]) + start_tx / 2;
777                         uint8_t* oY = yuv->data()[0] + (oy * yuv->stride()[0]) + start_ox;
778                         uint8_t* oU = yuv->data()[1] + (hoy * yuv->stride()[1]) + start_ox / 2;
779                         uint8_t* oV = yuv->data()[2] + (hoy * yuv->stride()[2]) + start_ox / 2;
780                         uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
781                         for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
782                                 float const a = float(alpha[3]) / 255;
783                                 *tY = *oY * a + *tY * (1 - a);
784                                 *tU = *oU * a + *tU * (1 - a);
785                                 *tV = *oV * a + *tV * (1 - a);
786                                 ++tY;
787                                 ++oY;
788                                 if (tx % 2) {
789                                         ++tU;
790                                         ++tV;
791                                 }
792                                 if (ox % 2) {
793                                         ++oU;
794                                         ++oV;
795                                 }
796                                 alpha += 4;
797                         }
798                 }
799                 break;
800         }
801         case AV_PIX_FMT_YUV420P10:
802         {
803                 auto yuv = other->convert_pixel_format (dcp::YUVToRGB::REC709, _pixel_format, Alignment::COMPACT, false);
804                 dcp::Size const ts = size();
805                 dcp::Size const os = yuv->size();
806                 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
807                         int const hty = ty / 2;
808                         int const hoy = oy / 2;
809                         uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
810                         uint16_t* tU = ((uint16_t *) (data()[1] + (hty * stride()[1]))) + start_tx / 2;
811                         uint16_t* tV = ((uint16_t *) (data()[2] + (hty * stride()[2]))) + start_tx / 2;
812                         uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
813                         uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (hoy * yuv->stride()[1]))) + start_ox / 2;
814                         uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (hoy * yuv->stride()[2]))) + start_ox / 2;
815                         uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
816                         for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
817                                 float const a = float(alpha[3]) / 255;
818                                 *tY = *oY * a + *tY * (1 - a);
819                                 *tU = *oU * a + *tU * (1 - a);
820                                 *tV = *oV * a + *tV * (1 - a);
821                                 ++tY;
822                                 ++oY;
823                                 if (tx % 2) {
824                                         ++tU;
825                                         ++tV;
826                                 }
827                                 if (ox % 2) {
828                                         ++oU;
829                                         ++oV;
830                                 }
831                                 alpha += 4;
832                         }
833                 }
834                 break;
835         }
836         case AV_PIX_FMT_YUV422P10LE:
837         {
838                 auto yuv = other->convert_pixel_format (dcp::YUVToRGB::REC709, _pixel_format, Alignment::COMPACT, false);
839                 dcp::Size const ts = size();
840                 dcp::Size const os = yuv->size();
841                 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
842                         uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
843                         uint16_t* tU = ((uint16_t *) (data()[1] + (ty * stride()[1]))) + start_tx / 2;
844                         uint16_t* tV = ((uint16_t *) (data()[2] + (ty * stride()[2]))) + start_tx / 2;
845                         uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
846                         uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (oy * yuv->stride()[1]))) + start_ox / 2;
847                         uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (oy * yuv->stride()[2]))) + start_ox / 2;
848                         uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
849                         for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
850                                 float const a = float(alpha[3]) / 255;
851                                 *tY = *oY * a + *tY * (1 - a);
852                                 *tU = *oU * a + *tU * (1 - a);
853                                 *tV = *oV * a + *tV * (1 - a);
854                                 ++tY;
855                                 ++oY;
856                                 if (tx % 2) {
857                                         ++tU;
858                                         ++tV;
859                                 }
860                                 if (ox % 2) {
861                                         ++oU;
862                                         ++oV;
863                                 }
864                                 alpha += 4;
865                         }
866                 }
867                 break;
868         }
869         default:
870                 throw PixelFormatError ("alpha_blend()", _pixel_format);
871         }
872 }
873
874
875 void
876 Image::copy (shared_ptr<const Image> other, Position<int> position)
877 {
878         /* Only implemented for RGB24 onto RGB24 so far */
879         DCPOMATIC_ASSERT (_pixel_format == AV_PIX_FMT_RGB24 && other->pixel_format() == AV_PIX_FMT_RGB24);
880         DCPOMATIC_ASSERT (position.x >= 0 && position.y >= 0);
881
882         int const N = min (position.x + other->size().width, size().width) - position.x;
883         for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
884                 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
885                 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
886                 memcpy (tp, op, N * 3);
887         }
888 }
889
890
891 void
892 Image::read_from_socket (shared_ptr<Socket> socket)
893 {
894         for (int i = 0; i < planes(); ++i) {
895                 uint8_t* p = data()[i];
896                 int const lines = sample_size(i).height;
897                 for (int y = 0; y < lines; ++y) {
898                         socket->read (p, line_size()[i]);
899                         p += stride()[i];
900                 }
901         }
902 }
903
904
905 void
906 Image::write_to_socket (shared_ptr<Socket> socket) const
907 {
908         for (int i = 0; i < planes(); ++i) {
909                 uint8_t* p = data()[i];
910                 int const lines = sample_size(i).height;
911                 for (int y = 0; y < lines; ++y) {
912                         socket->write (p, line_size()[i]);
913                         p += stride()[i];
914                 }
915         }
916 }
917
918
919 float
920 Image::bytes_per_pixel (int c) const
921 {
922         auto d = av_pix_fmt_desc_get(_pixel_format);
923         if (!d) {
924                 throw PixelFormatError ("bytes_per_pixel()", _pixel_format);
925         }
926
927         if (c >= planes()) {
928                 return 0;
929         }
930
931         float bpp[4] = { 0, 0, 0, 0 };
932
933 #ifdef DCPOMATIC_HAVE_AVCOMPONENTDESCRIPTOR_DEPTH_MINUS1
934         bpp[0] = floor ((d->comp[0].depth_minus1 + 8) / 8);
935         if (d->nb_components > 1) {
936                 bpp[1] = floor ((d->comp[1].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
937         }
938         if (d->nb_components > 2) {
939                 bpp[2] = floor ((d->comp[2].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
940         }
941         if (d->nb_components > 3) {
942                 bpp[3] = floor ((d->comp[3].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
943         }
944 #else
945         bpp[0] = floor ((d->comp[0].depth + 7) / 8);
946         if (d->nb_components > 1) {
947                 bpp[1] = floor ((d->comp[1].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
948         }
949         if (d->nb_components > 2) {
950                 bpp[2] = floor ((d->comp[2].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
951         }
952         if (d->nb_components > 3) {
953                 bpp[3] = floor ((d->comp[3].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
954         }
955 #endif
956
957         if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
958                 /* Not planar; sum them up */
959                 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
960         }
961
962         return bpp[c];
963 }
964
965
966 /** Construct a Image of a given size and format, allocating memory
967  *  as required.
968  *
969  *  @param p Pixel format.
970  *  @param s Size in pixels.
971  *  @param alignment PADDED to make each row of this image aligned to a ALIGNMENT-byte boundary, otherwise COMPACT.
972  */
973 Image::Image (AVPixelFormat p, dcp::Size s, Alignment alignment)
974         : _size (s)
975         , _pixel_format (p)
976         , _alignment (alignment)
977 {
978         allocate ();
979 }
980
981
982 void
983 Image::allocate ()
984 {
985         _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
986         _data[0] = _data[1] = _data[2] = _data[3] = 0;
987
988         _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
989         _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
990
991         _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
992         _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
993
994         auto stride_round_up = [](int stride, int t) {
995                 int const a = stride + (t - 1);
996                 return a - (a % t);
997         };
998
999         for (int i = 0; i < planes(); ++i) {
1000                 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
1001                 _stride[i] = stride_round_up (_line_size[i], _alignment == Alignment::PADDED ? ALIGNMENT : 1);
1002
1003                 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
1004                    uses a 16-byte fetch to read three bytes (R/G/B) of image data.
1005                    Hence on the last pixel of the last line it reads over the end of
1006                    the actual data by 1 byte.  If the width of an image is a multiple
1007                    of the stride alignment there will be no padding at the end of image lines.
1008                    OS X crashes on this illegal read, though other operating systems don't
1009                    seem to mind.  The nasty + 1 in this malloc makes sure there is always a byte
1010                    for that instruction to read safely.
1011
1012                    Further to the above, valgrind is now telling me that ff_rgb24ToY_ssse3
1013                    over-reads by more then _avx.  I can't follow the code to work out how much,
1014                    so I'll just over-allocate by ALIGNMENT bytes and have done with it.  Empirical
1015                    testing suggests that it works.
1016
1017                    In addition to these concerns, we may read/write as much as a whole extra line
1018                    at the end of each plane in cases where we are messing with offsets in order to
1019                    do pad or crop.  To solve this we over-allocate by an extra _stride[i] bytes.
1020
1021                    As an example: we may write to images starting at an offset so we get some padding.
1022                    Hence we want to write in the following pattern:
1023
1024                    block start   write start                                  line end
1025                    |..(padding)..|<------line-size------------->|..(padding)..|
1026                    |..(padding)..|<------line-size------------->|..(padding)..|
1027                    |..(padding)..|<------line-size------------->|..(padding)..|
1028
1029                    where line-size is of the smaller (inter_size) image and the full padded line length is that of
1030                    out_size.  To get things to work we have to tell FFmpeg that the stride is that of out_size.
1031                    However some parts of FFmpeg (notably rgb48Toxyz12 in swscale.c) process data for the full
1032                    specified *stride*.  This does not matter until we get to the last line:
1033
1034                    block start   write start                                  line end
1035                    |..(padding)..|<------line-size------------->|XXXwrittenXXX|
1036                    |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXX|
1037                    |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXXXXXwrittenXXX
1038                                                                                ^^^^ out of bounds
1039                 */
1040                 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * (sample_size(i).height + 1) + ALIGNMENT);
1041 #if HAVE_VALGRIND_MEMCHECK_H
1042                 /* The data between the end of the line size and the stride is undefined but processed by
1043                    libswscale, causing lots of valgrind errors.  Mark it all defined to quell these errors.
1044                 */
1045                 VALGRIND_MAKE_MEM_DEFINED (_data[i], _stride[i] * (sample_size(i).height + 1) + ALIGNMENT);
1046 #endif
1047         }
1048 }
1049
1050
1051 Image::Image (Image const & other)
1052         : std::enable_shared_from_this<Image>(other)
1053         , _size (other._size)
1054         , _pixel_format (other._pixel_format)
1055         , _alignment (other._alignment)
1056 {
1057         allocate ();
1058
1059         for (int i = 0; i < planes(); ++i) {
1060                 uint8_t* p = _data[i];
1061                 uint8_t* q = other._data[i];
1062                 int const lines = sample_size(i).height;
1063                 for (int j = 0; j < lines; ++j) {
1064                         memcpy (p, q, _line_size[i]);
1065                         p += stride()[i];
1066                         q += other.stride()[i];
1067                 }
1068         }
1069 }
1070
1071
1072 Image::Image (AVFrame const * frame, Alignment alignment)
1073         : _size (frame->width, frame->height)
1074         , _pixel_format (static_cast<AVPixelFormat>(frame->format))
1075         , _alignment (alignment)
1076 {
1077         DCPOMATIC_ASSERT (_pixel_format != AV_PIX_FMT_NONE);
1078
1079         allocate ();
1080
1081         for (int i = 0; i < planes(); ++i) {
1082                 uint8_t* p = _data[i];
1083                 uint8_t* q = frame->data[i];
1084                 int const lines = sample_size(i).height;
1085                 for (int j = 0; j < lines; ++j) {
1086                         memcpy (p, q, _line_size[i]);
1087                         p += stride()[i];
1088                         /* AVFrame's linesize is what we call `stride' */
1089                         q += frame->linesize[i];
1090                 }
1091         }
1092 }
1093
1094
1095 Image::Image (shared_ptr<const Image> other, Alignment alignment)
1096         : _size (other->_size)
1097         , _pixel_format (other->_pixel_format)
1098         , _alignment (alignment)
1099 {
1100         allocate ();
1101
1102         for (int i = 0; i < planes(); ++i) {
1103                 DCPOMATIC_ASSERT (line_size()[i] == other->line_size()[i]);
1104                 uint8_t* p = _data[i];
1105                 uint8_t* q = other->data()[i];
1106                 int const lines = sample_size(i).height;
1107                 for (int j = 0; j < lines; ++j) {
1108                         memcpy (p, q, line_size()[i]);
1109                         p += stride()[i];
1110                         q += other->stride()[i];
1111                 }
1112         }
1113 }
1114
1115
1116 Image&
1117 Image::operator= (Image const & other)
1118 {
1119         if (this == &other) {
1120                 return *this;
1121         }
1122
1123         Image tmp (other);
1124         swap (tmp);
1125         return *this;
1126 }
1127
1128
1129 void
1130 Image::swap (Image & other)
1131 {
1132         std::swap (_size, other._size);
1133         std::swap (_pixel_format, other._pixel_format);
1134
1135         for (int i = 0; i < 4; ++i) {
1136                 std::swap (_data[i], other._data[i]);
1137                 std::swap (_line_size[i], other._line_size[i]);
1138                 std::swap (_stride[i], other._stride[i]);
1139         }
1140
1141         std::swap (_alignment, other._alignment);
1142 }
1143
1144
1145 Image::~Image ()
1146 {
1147         for (int i = 0; i < planes(); ++i) {
1148                 av_free (_data[i]);
1149         }
1150
1151         av_free (_data);
1152         av_free (_line_size);
1153         av_free (_stride);
1154 }
1155
1156
1157 uint8_t * const *
1158 Image::data () const
1159 {
1160         return _data;
1161 }
1162
1163
1164 int const *
1165 Image::line_size () const
1166 {
1167         return _line_size;
1168 }
1169
1170
1171 int const *
1172 Image::stride () const
1173 {
1174         return _stride;
1175 }
1176
1177
1178 dcp::Size
1179 Image::size () const
1180 {
1181         return _size;
1182 }
1183
1184
1185 Image::Alignment
1186 Image::alignment () const
1187 {
1188         return _alignment;
1189 }
1190
1191
1192 PositionImage
1193 merge (list<PositionImage> images, Image::Alignment alignment)
1194 {
1195         if (images.empty ()) {
1196                 return {};
1197         }
1198
1199         if (images.size() == 1) {
1200                 images.front().image = Image::ensure_alignment(images.front().image, alignment);
1201                 return images.front();
1202         }
1203
1204         dcpomatic::Rect<int> all (images.front().position, images.front().image->size().width, images.front().image->size().height);
1205         for (auto const& i: images) {
1206                 all.extend (dcpomatic::Rect<int>(i.position, i.image->size().width, i.image->size().height));
1207         }
1208
1209         auto merged = make_shared<Image>(images.front().image->pixel_format(), dcp::Size(all.width, all.height), alignment);
1210         merged->make_transparent ();
1211         for (auto const& i: images) {
1212                 merged->alpha_blend (i.image, i.position - all.position());
1213         }
1214
1215         return PositionImage (merged, all.position ());
1216 }
1217
1218
1219 bool
1220 operator== (Image const & a, Image const & b)
1221 {
1222         if (a.planes() != b.planes() || a.pixel_format() != b.pixel_format() || a.alignment() != b.alignment()) {
1223                 return false;
1224         }
1225
1226         for (int c = 0; c < a.planes(); ++c) {
1227                 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]) {
1228                         return false;
1229                 }
1230
1231                 uint8_t* p = a.data()[c];
1232                 uint8_t* q = b.data()[c];
1233                 int const lines = a.sample_size(c).height;
1234                 for (int y = 0; y < lines; ++y) {
1235                         if (memcmp (p, q, a.line_size()[c]) != 0) {
1236                                 return false;
1237                         }
1238
1239                         p += a.stride()[c];
1240                         q += b.stride()[c];
1241                 }
1242         }
1243
1244         return true;
1245 }
1246
1247
1248 /** Fade the image.
1249  *  @param f Amount to fade by; 0 is black, 1 is no fade.
1250  */
1251 void
1252 Image::fade (float f)
1253 {
1254         /* U/V black value for 8-bit colour */
1255         static int const eight_bit_uv =    (1 << 7) - 1;
1256         /* U/V black value for 10-bit colour */
1257         static uint16_t const ten_bit_uv = (1 << 9) - 1;
1258
1259         switch (_pixel_format) {
1260         case AV_PIX_FMT_YUV420P:
1261         {
1262                 /* Y */
1263                 uint8_t* p = data()[0];
1264                 int const lines = sample_size(0).height;
1265                 for (int y = 0; y < lines; ++y) {
1266                         uint8_t* q = p;
1267                         for (int x = 0; x < line_size()[0]; ++x) {
1268                                 *q = int(float(*q) * f);
1269                                 ++q;
1270                         }
1271                         p += stride()[0];
1272                 }
1273
1274                 /* U, V */
1275                 for (int c = 1; c < 3; ++c) {
1276                         uint8_t* p = data()[c];
1277                         int const lines = sample_size(c).height;
1278                         for (int y = 0; y < lines; ++y) {
1279                                 uint8_t* q = p;
1280                                 for (int x = 0; x < line_size()[c]; ++x) {
1281                                         *q = eight_bit_uv + int((int(*q) - eight_bit_uv) * f);
1282                                         ++q;
1283                                 }
1284                                 p += stride()[c];
1285                         }
1286                 }
1287
1288                 break;
1289         }
1290
1291         case AV_PIX_FMT_RGB24:
1292         {
1293                 /* 8-bit */
1294                 uint8_t* p = data()[0];
1295                 int const lines = sample_size(0).height;
1296                 for (int y = 0; y < lines; ++y) {
1297                         uint8_t* q = p;
1298                         for (int x = 0; x < line_size()[0]; ++x) {
1299                                 *q = int (float (*q) * f);
1300                                 ++q;
1301                         }
1302                         p += stride()[0];
1303                 }
1304                 break;
1305         }
1306
1307         case AV_PIX_FMT_XYZ12LE:
1308         case AV_PIX_FMT_RGB48LE:
1309                 /* 16-bit little-endian */
1310                 for (int c = 0; c < 3; ++c) {
1311                         int const stride_pixels = stride()[c] / 2;
1312                         int const line_size_pixels = line_size()[c] / 2;
1313                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1314                         int const lines = sample_size(c).height;
1315                         for (int y = 0; y < lines; ++y) {
1316                                 uint16_t* q = p;
1317                                 for (int x = 0; x < line_size_pixels; ++x) {
1318                                         *q = int (float (*q) * f);
1319                                         ++q;
1320                                 }
1321                                 p += stride_pixels;
1322                         }
1323                 }
1324                 break;
1325
1326         case AV_PIX_FMT_YUV422P10LE:
1327         {
1328                 /* Y */
1329                 {
1330                         int const stride_pixels = stride()[0] / 2;
1331                         int const line_size_pixels = line_size()[0] / 2;
1332                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[0]);
1333                         int const lines = sample_size(0).height;
1334                         for (int y = 0; y < lines; ++y) {
1335                                 uint16_t* q = p;
1336                                 for (int x = 0; x < line_size_pixels; ++x) {
1337                                         *q = int(float(*q) * f);
1338                                         ++q;
1339                                 }
1340                                 p += stride_pixels;
1341                         }
1342                 }
1343
1344                 /* U, V */
1345                 for (int c = 1; c < 3; ++c) {
1346                         int const stride_pixels = stride()[c] / 2;
1347                         int const line_size_pixels = line_size()[c] / 2;
1348                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1349                         int const lines = sample_size(c).height;
1350                         for (int y = 0; y < lines; ++y) {
1351                                 uint16_t* q = p;
1352                                 for (int x = 0; x < line_size_pixels; ++x) {
1353                                         *q = ten_bit_uv + int((int(*q) - ten_bit_uv) * f);
1354                                         ++q;
1355                                 }
1356                                 p += stride_pixels;
1357                         }
1358                 }
1359                 break;
1360
1361         }
1362
1363         default:
1364                 throw PixelFormatError ("fade()", _pixel_format);
1365         }
1366 }
1367
1368
1369 shared_ptr<const Image>
1370 Image::ensure_alignment (shared_ptr<const Image> image, Image::Alignment alignment)
1371 {
1372         if (image->alignment() == alignment) {
1373                 return image;
1374         }
1375
1376         return make_shared<Image>(image, alignment);
1377 }
1378
1379
1380 size_t
1381 Image::memory_used () const
1382 {
1383         size_t m = 0;
1384         for (int i = 0; i < planes(); ++i) {
1385                 m += _stride[i] * sample_size(i).height;
1386         }
1387         return m;
1388 }
1389
1390
1391 void
1392 Image::video_range_to_full_range ()
1393 {
1394         switch (_pixel_format) {
1395         case AV_PIX_FMT_RGB24:
1396         {
1397                 float const factor = 256.0 / 219.0;
1398                 uint8_t* p = data()[0];
1399                 int const lines = sample_size(0).height;
1400                 for (int y = 0; y < lines; ++y) {
1401                         uint8_t* q = p;
1402                         for (int x = 0; x < line_size()[0]; ++x) {
1403                                 *q = clamp(lrintf((*q - 16) * factor), 0L, 255L);
1404                                 ++q;
1405                         }
1406                         p += stride()[0];
1407                 }
1408                 break;
1409         }
1410         case AV_PIX_FMT_RGB48LE:
1411         {
1412                 float const factor = 65536.0 / 56064.0;
1413                 uint16_t* p = reinterpret_cast<uint16_t*>(data()[0]);
1414                 int const lines = sample_size(0).height;
1415                 for (int y = 0; y < lines; ++y) {
1416                         uint16_t* q = p;
1417                         int const line_size_pixels = line_size()[0] / 2;
1418                         for (int x = 0; x < line_size_pixels; ++x) {
1419                                 *q = clamp(lrintf((*q - 4096) * factor), 0L, 65535L);
1420                                 ++q;
1421                         }
1422                         p += stride()[0] / 2;
1423                 }
1424                 break;
1425         }
1426         case AV_PIX_FMT_GBRP12LE:
1427         {
1428                 float const factor = 4096.0 / 3504.0;
1429                 for (int c = 0; c < 3; ++c) {
1430                         uint16_t* p = reinterpret_cast<uint16_t*>(data()[c]);
1431                         int const lines = sample_size(c).height;
1432                         for (int y = 0; y < lines; ++y) {
1433                                 uint16_t* q = p;
1434                                 int const line_size_pixels = line_size()[c] / 2;
1435                                 for (int x = 0; x < line_size_pixels; ++x) {
1436                                         *q = clamp(lrintf((*q - 256) * factor), 0L, 4095L);
1437                                         ++q;
1438                                 }
1439                         }
1440                 }
1441                 break;
1442         }
1443         default:
1444                 throw PixelFormatError ("video_range_to_full_range()", _pixel_format);
1445         }
1446 }
1447