Fix d881836379172f4072ed81ea074f46b3a363a681 which removed clearing
[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 "exceptions.h"
31 #include "image.h"
32 #include "maths_util.h"
33 #include "memory_util.h"
34 #include "rect.h"
35 #include "timer.h"
36 #include <dcp/rgb_xyz.h>
37 #include <dcp/transfer_function.h>
38 #include <dcp/warnings.h>
39 LIBDCP_DISABLE_WARNINGS
40 extern "C" {
41 #include <libavutil/frame.h>
42 #include <libavutil/pixdesc.h>
43 #include <libavutil/pixfmt.h>
44 #include <libswscale/swscale.h>
45 }
46 LIBDCP_ENABLE_WARNINGS
47 #if HAVE_VALGRIND_MEMCHECK_H
48 #include <valgrind/memcheck.h>
49 #endif
50 #include <iostream>
51
52
53 #include "i18n.h"
54
55
56 using std::cerr;
57 using std::cout;
58 using std::list;
59 using std::make_shared;
60 using std::max;
61 using std::min;
62 using std::runtime_error;
63 using std::shared_ptr;
64 using std::string;
65 using dcp::Size;
66
67
68 /** The memory alignment, in bytes, used for each row of an image if Alignment::PADDED is requested */
69 int constexpr ALIGNMENT = 64;
70
71 /* U/V black value for 8-bit colour */
72 static uint8_t const eight_bit_uv =     (1 << 7) - 1;
73 /* U/V black value for 9-bit colour */
74 static uint16_t const nine_bit_uv =     (1 << 8) - 1;
75 /* U/V black value for 10-bit colour */
76 static uint16_t const ten_bit_uv =      (1 << 9) - 1;
77 /* U/V black value for 16-bit colour */
78 static uint16_t const sixteen_bit_uv =  (1 << 15) - 1;
79
80
81 int
82 Image::vertical_factor (int n) const
83 {
84         if (n == 0) {
85                 return 1;
86         }
87
88         auto d = av_pix_fmt_desc_get(_pixel_format);
89         if (!d) {
90                 throw PixelFormatError ("line_factor()", _pixel_format);
91         }
92
93         return lrintf(powf(2.0f, d->log2_chroma_h));
94 }
95
96 int
97 Image::horizontal_factor (int n) const
98 {
99         if (n == 0) {
100                 return 1;
101         }
102
103         auto d = av_pix_fmt_desc_get(_pixel_format);
104         if (!d) {
105                 throw PixelFormatError ("sample_size()", _pixel_format);
106         }
107
108         return lrintf(powf(2.0f, d->log2_chroma_w));
109 }
110
111
112 /** @param n Component index.
113  *  @return Number of samples (i.e. pixels, unless sub-sampled) in each direction for this component.
114  */
115 dcp::Size
116 Image::sample_size (int n) const
117 {
118         return dcp::Size (
119                 lrint (ceil(static_cast<double>(size().width) / horizontal_factor(n))),
120                 lrint (ceil(static_cast<double>(size().height) / vertical_factor(n)))
121                 );
122 }
123
124
125 /** @return Number of planes */
126 int
127 Image::planes () const
128 {
129         if (_pixel_format == AV_PIX_FMT_PAL8) {
130                 return 2;
131         }
132
133         auto d = av_pix_fmt_desc_get(_pixel_format);
134         if (!d) {
135                 throw PixelFormatError ("planes()", _pixel_format);
136         }
137
138         if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
139                 return 1;
140         }
141
142         return d->nb_components;
143 }
144
145
146 static
147 int
148 round_width_for_subsampling (int p, AVPixFmtDescriptor const * desc)
149 {
150         return p & ~ ((1 << desc->log2_chroma_w) - 1);
151 }
152
153
154 static
155 int
156 round_height_for_subsampling (int p, AVPixFmtDescriptor const * desc)
157 {
158         return p & ~ ((1 << desc->log2_chroma_h) - 1);
159 }
160
161
162 /** Crop this image, scale it to `inter_size' and then place it in a black frame of `out_size'.
163  *  @param crop Amount to crop by.
164  *  @param inter_size Size to scale the cropped image to.
165  *  @param out_size Size of output frame; if this is larger than inter_size there will be black padding.
166  *  @param yuv_to_rgb YUV to RGB transformation to use, if required.
167  *  @param video_range Video range of the image.
168  *  @param out_format Output pixel format.
169  *  @param out_aligned true to make the output image aligned.
170  *  @param out_video_range Video range to use for the output image.
171  *  @param fast Try to be fast at the possible expense of quality; at present this means using
172  *  fast bilinear rather than bicubic scaling.
173  */
174 shared_ptr<Image>
175 Image::crop_scale_window (
176         Crop crop,
177         dcp::Size inter_size,
178         dcp::Size out_size,
179         dcp::YUVToRGB yuv_to_rgb,
180         VideoRange video_range,
181         AVPixelFormat out_format,
182         VideoRange out_video_range,
183         Alignment out_alignment,
184         bool fast
185         ) const
186 {
187         /* Empirical testing suggests that sws_scale() will crash if
188            the input image is not padded.
189         */
190         DCPOMATIC_ASSERT (alignment() == Alignment::PADDED);
191
192         DCPOMATIC_ASSERT (out_size.width >= inter_size.width);
193         DCPOMATIC_ASSERT (out_size.height >= inter_size.height);
194
195         auto out = make_shared<Image>(out_format, out_size, out_alignment);
196         out->make_black ();
197
198         auto in_desc = av_pix_fmt_desc_get (_pixel_format);
199         if (!in_desc) {
200                 throw PixelFormatError ("crop_scale_window()", _pixel_format);
201         }
202
203         /* Round down so that we crop only the number of pixels that is straightforward
204          * considering any subsampling.
205          */
206         Crop corrected_crop(
207                 round_width_for_subsampling(crop.left, in_desc),
208                 round_width_for_subsampling(crop.right, in_desc),
209                 round_height_for_subsampling(crop.top, in_desc),
210                 round_height_for_subsampling(crop.bottom, in_desc)
211                 );
212
213         /* Also check that we aren't cropping more image than there actually is */
214         if ((corrected_crop.left + corrected_crop.right) >= (size().width - 4)) {
215                 corrected_crop.left = 0;
216                 corrected_crop.right = size().width - 4;
217         }
218
219         if ((corrected_crop.top + corrected_crop.bottom) >= (size().height - 4)) {
220                 corrected_crop.top = 0;
221                 corrected_crop.bottom = size().height - 4;
222         }
223
224         /* Size of the image after any crop */
225         auto const cropped_size = corrected_crop.apply (size());
226
227         /* Scale context for a scale from cropped_size to inter_size */
228         auto scale_context = sws_getContext (
229                         cropped_size.width, cropped_size.height, pixel_format(),
230                         inter_size.width, inter_size.height, out_format,
231                         fast ? SWS_FAST_BILINEAR : SWS_BICUBIC, 0, 0, 0
232                 );
233
234         if (!scale_context) {
235                 throw runtime_error (N_("Could not allocate SwsContext"));
236         }
237
238         DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUVToRGB::COUNT);
239         int const lut[static_cast<int>(dcp::YUVToRGB::COUNT)] = {
240                 SWS_CS_ITU601,
241                 SWS_CS_ITU709
242         };
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[static_cast<int>(yuv_to_rgb)]), video_range == VideoRange::VIDEO ? 0 : 1,
258                 sws_getCoefficients (lut[static_cast<int>(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         int const lut[static_cast<int>(dcp::YUVToRGB::COUNT)] = {
351                 SWS_CS_ITU601,
352                 SWS_CS_ITU709
353         };
354
355         /* The 3rd parameter here is:
356            0 -> source range MPEG (i.e. "video", 16-235)
357            1 -> source range JPEG (i.e. "full", 0-255)
358            And the 5th:
359            0 -> destination range MPEG (i.e. "video", 16-235)
360            1 -> destination range JPEG (i.e. "full", 0-255)
361
362            But remember: sws_setColorspaceDetails ignores these
363            parameters unless the corresponding image isYUV or isGray.
364            (If it's neither, it uses video range).
365         */
366         sws_setColorspaceDetails (
367                 scale_context,
368                 sws_getCoefficients (lut[static_cast<int>(yuv_to_rgb)]), 0,
369                 sws_getCoefficients (lut[static_cast<int>(yuv_to_rgb)]), 0,
370                 0, 1 << 16, 1 << 16
371                 );
372
373         sws_scale (
374                 scale_context,
375                 data(), stride(),
376                 0, size().height,
377                 scaled->data(), scaled->stride()
378                 );
379
380         sws_freeContext (scale_context);
381
382         return scaled;
383 }
384
385
386 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
387 void
388 Image::yuv_16_black (uint16_t v, bool alpha)
389 {
390         memset (data()[0], 0, sample_size(0).height * stride()[0]);
391         for (int i = 1; i < 3; ++i) {
392                 auto p = reinterpret_cast<int16_t*> (data()[i]);
393                 int const lines = sample_size(i).height;
394                 for (int y = 0; y < lines; ++y) {
395                         /* We divide by 2 here because we are writing 2 bytes at a time */
396                         for (int x = 0; x < line_size()[i] / 2; ++x) {
397                                 p[x] = v;
398                         }
399                         p += stride()[i] / 2;
400                 }
401         }
402
403         if (alpha) {
404                 memset (data()[3], 0, sample_size(3).height * stride()[3]);
405         }
406 }
407
408
409 uint16_t
410 Image::swap_16 (uint16_t v)
411 {
412         return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
413 }
414
415
416 void
417 Image::make_part_black (int const start, int const width)
418 {
419         auto y_part = [&]() {
420                 int const bpp = bytes_per_pixel(0);
421                 int const h = sample_size(0).height;
422                 int const s = stride()[0];
423                 auto p = data()[0];
424                 for (int y = 0; y < h; ++y) {
425                         memset (p + start * bpp, 0, width * bpp);
426                         p += s;
427                 }
428         };
429
430         switch (_pixel_format) {
431         case AV_PIX_FMT_RGB24:
432         case AV_PIX_FMT_ARGB:
433         case AV_PIX_FMT_RGBA:
434         case AV_PIX_FMT_ABGR:
435         case AV_PIX_FMT_BGRA:
436         case AV_PIX_FMT_RGB555LE:
437         case AV_PIX_FMT_RGB48LE:
438         case AV_PIX_FMT_RGB48BE:
439         case AV_PIX_FMT_XYZ12LE:
440         {
441                 int const h = sample_size(0).height;
442                 int const bpp = bytes_per_pixel(0);
443                 int const s = stride()[0];
444                 uint8_t* p = data()[0];
445                 for (int y = 0; y < h; y++) {
446                         memset (p + start * bpp, 0, width * bpp);
447                         p += s;
448                 }
449                 break;
450         }
451         case AV_PIX_FMT_YUV420P:
452         {
453                 y_part ();
454                 for (int i = 1; i < 3; ++i) {
455                         auto p = data()[i];
456                         int const h = sample_size(i).height;
457                         for (int y = 0; y < h; ++y) {
458                                 for (int x = start / 2; x < (start + width) / 2; ++x) {
459                                         p[x] = eight_bit_uv;
460                                 }
461                                 p += stride()[i];
462                         }
463                 }
464                 break;
465         }
466         case AV_PIX_FMT_YUV422P10LE:
467         {
468                 y_part ();
469                 for (int i = 1; i < 3; ++i) {
470                         auto p = reinterpret_cast<int16_t*>(data()[i]);
471                         int const h = sample_size(i).height;
472                         for (int y = 0; y < h; ++y) {
473                                 for (int x = start / 2; x < (start + width) / 2; ++x) {
474                                         p[x] = ten_bit_uv;
475                                 }
476                                 p += stride()[i] / 2;
477                         }
478                 }
479                 break;
480         }
481         default:
482                 throw PixelFormatError ("make_part_black()", _pixel_format);
483         }
484 }
485
486
487 void
488 Image::make_black ()
489 {
490         switch (_pixel_format) {
491         case AV_PIX_FMT_YUV420P:
492         case AV_PIX_FMT_YUV422P:
493         case AV_PIX_FMT_YUV444P:
494         case AV_PIX_FMT_YUV411P:
495                 memset (data()[0], 0, sample_size(0).height * stride()[0]);
496                 memset (data()[1], eight_bit_uv, sample_size(1).height * stride()[1]);
497                 memset (data()[2], eight_bit_uv, sample_size(2).height * stride()[2]);
498                 break;
499
500         case AV_PIX_FMT_YUVJ420P:
501         case AV_PIX_FMT_YUVJ422P:
502         case AV_PIX_FMT_YUVJ444P:
503                 memset (data()[0], 0, sample_size(0).height * stride()[0]);
504                 memset (data()[1], eight_bit_uv + 1, sample_size(1).height * stride()[1]);
505                 memset (data()[2], eight_bit_uv + 1, sample_size(2).height * stride()[2]);
506                 break;
507
508         case AV_PIX_FMT_YUV422P9LE:
509         case AV_PIX_FMT_YUV444P9LE:
510                 yuv_16_black (nine_bit_uv, false);
511                 break;
512
513         case AV_PIX_FMT_YUV422P9BE:
514         case AV_PIX_FMT_YUV444P9BE:
515                 yuv_16_black (swap_16 (nine_bit_uv), false);
516                 break;
517
518         case AV_PIX_FMT_YUV422P10LE:
519         case AV_PIX_FMT_YUV444P10LE:
520                 yuv_16_black (ten_bit_uv, false);
521                 break;
522
523         case AV_PIX_FMT_YUV422P16LE:
524         case AV_PIX_FMT_YUV444P16LE:
525                 yuv_16_black (sixteen_bit_uv, false);
526                 break;
527
528         case AV_PIX_FMT_YUV444P10BE:
529         case AV_PIX_FMT_YUV422P10BE:
530                 yuv_16_black (swap_16 (ten_bit_uv), false);
531                 break;
532
533         case AV_PIX_FMT_YUVA420P9BE:
534         case AV_PIX_FMT_YUVA422P9BE:
535         case AV_PIX_FMT_YUVA444P9BE:
536                 yuv_16_black (swap_16 (nine_bit_uv), true);
537                 break;
538
539         case AV_PIX_FMT_YUVA420P9LE:
540         case AV_PIX_FMT_YUVA422P9LE:
541         case AV_PIX_FMT_YUVA444P9LE:
542                 yuv_16_black (nine_bit_uv, true);
543                 break;
544
545         case AV_PIX_FMT_YUVA420P10BE:
546         case AV_PIX_FMT_YUVA422P10BE:
547         case AV_PIX_FMT_YUVA444P10BE:
548                 yuv_16_black (swap_16 (ten_bit_uv), true);
549                 break;
550
551         case AV_PIX_FMT_YUVA420P10LE:
552         case AV_PIX_FMT_YUVA422P10LE:
553         case AV_PIX_FMT_YUVA444P10LE:
554                 yuv_16_black (ten_bit_uv, true);
555                 break;
556
557         case AV_PIX_FMT_YUVA420P16BE:
558         case AV_PIX_FMT_YUVA422P16BE:
559         case AV_PIX_FMT_YUVA444P16BE:
560                 yuv_16_black (swap_16 (sixteen_bit_uv), true);
561                 break;
562
563         case AV_PIX_FMT_YUVA420P16LE:
564         case AV_PIX_FMT_YUVA422P16LE:
565         case AV_PIX_FMT_YUVA444P16LE:
566                 yuv_16_black (sixteen_bit_uv, true);
567                 break;
568
569         case AV_PIX_FMT_RGB24:
570         case AV_PIX_FMT_ARGB:
571         case AV_PIX_FMT_RGBA:
572         case AV_PIX_FMT_ABGR:
573         case AV_PIX_FMT_BGRA:
574         case AV_PIX_FMT_RGB555LE:
575         case AV_PIX_FMT_RGB48LE:
576         case AV_PIX_FMT_RGB48BE:
577         case AV_PIX_FMT_XYZ12LE:
578                 memset (data()[0], 0, sample_size(0).height * stride()[0]);
579                 break;
580
581         case AV_PIX_FMT_UYVY422:
582         {
583                 int const Y = sample_size(0).height;
584                 int const X = line_size()[0];
585                 uint8_t* p = data()[0];
586                 for (int y = 0; y < Y; ++y) {
587                         for (int x = 0; x < X / 4; ++x) {
588                                 *p++ = eight_bit_uv; // Cb
589                                 *p++ = 0;            // Y0
590                                 *p++ = eight_bit_uv; // Cr
591                                 *p++ = 0;            // Y1
592                         }
593                 }
594                 break;
595         }
596
597         default:
598                 throw PixelFormatError ("make_black()", _pixel_format);
599         }
600 }
601
602
603 void
604 Image::make_transparent ()
605 {
606         if (_pixel_format != AV_PIX_FMT_BGRA && _pixel_format != AV_PIX_FMT_RGBA) {
607                 throw PixelFormatError ("make_transparent()", _pixel_format);
608         }
609
610         memset (data()[0], 0, sample_size(0).height * stride()[0]);
611 }
612
613
614 void
615 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
616 {
617         /* We're blending RGBA or BGRA images */
618         DCPOMATIC_ASSERT (other->pixel_format() == AV_PIX_FMT_BGRA || other->pixel_format() == AV_PIX_FMT_RGBA);
619         int const blue = other->pixel_format() == AV_PIX_FMT_BGRA ? 0 : 2;
620         int const red = other->pixel_format() == AV_PIX_FMT_BGRA ? 2 : 0;
621
622         int const other_bpp = 4;
623
624         int start_tx = position.x;
625         int start_ox = 0;
626
627         if (start_tx < 0) {
628                 start_ox = -start_tx;
629                 start_tx = 0;
630         }
631
632         int start_ty = position.y;
633         int start_oy = 0;
634
635         if (start_ty < 0) {
636                 start_oy = -start_ty;
637                 start_ty = 0;
638         }
639
640         switch (_pixel_format) {
641         case AV_PIX_FMT_RGB24:
642         {
643                 /* Going onto RGB24.  First byte is red, second green, third blue */
644                 int const this_bpp = 3;
645                 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
646                         uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
647                         uint8_t* op = other->data()[0] + oy * other->stride()[0];
648                         for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
649                                 float const alpha = float (op[3]) / 255;
650                                 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
651                                 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
652                                 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
653
654                                 tp += this_bpp;
655                                 op += other_bpp;
656                         }
657                 }
658                 break;
659         }
660         case AV_PIX_FMT_BGRA:
661         {
662                 int const this_bpp = 4;
663                 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
664                         uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
665                         uint8_t* op = other->data()[0] + oy * other->stride()[0];
666                         for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
667                                 float const alpha = float (op[3]) / 255;
668                                 tp[0] = op[blue] * alpha + tp[0] * (1 - alpha);
669                                 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
670                                 tp[2] = op[red] * alpha + tp[2] * (1 - alpha);
671                                 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
672
673                                 tp += this_bpp;
674                                 op += other_bpp;
675                         }
676                 }
677                 break;
678         }
679         case AV_PIX_FMT_RGBA:
680         {
681                 int const this_bpp = 4;
682                 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
683                         uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
684                         uint8_t* op = other->data()[0] + oy * other->stride()[0];
685                         for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
686                                 float const alpha = float (op[3]) / 255;
687                                 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
688                                 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
689                                 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
690                                 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
691
692                                 tp += this_bpp;
693                                 op += other_bpp;
694                         }
695                 }
696                 break;
697         }
698         case AV_PIX_FMT_RGB48LE:
699         {
700                 int const this_bpp = 6;
701                 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
702                         uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
703                         uint8_t* op = other->data()[0] + oy * other->stride()[0];
704                         for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
705                                 float const alpha = float (op[3]) / 255;
706                                 /* Blend high bytes */
707                                 tp[1] = op[red] * alpha + tp[1] * (1 - alpha);
708                                 tp[3] = op[1] * alpha + tp[3] * (1 - alpha);
709                                 tp[5] = op[blue] * alpha + tp[5] * (1 - alpha);
710
711                                 tp += this_bpp;
712                                 op += other_bpp;
713                         }
714                 }
715                 break;
716         }
717         case AV_PIX_FMT_XYZ12LE:
718         {
719                 auto conv = dcp::ColourConversion::srgb_to_xyz();
720                 double fast_matrix[9];
721                 dcp::combined_rgb_to_xyz (conv, fast_matrix);
722                 auto lut_in = conv.in()->lut(0, 1, 8, false);
723                 auto lut_out = conv.out()->lut(0, 1, 16, true);
724                 int const this_bpp = 6;
725                 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
726                         uint16_t* tp = reinterpret_cast<uint16_t*> (data()[0] + ty * stride()[0] + start_tx * this_bpp);
727                         uint8_t* op = other->data()[0] + oy * other->stride()[0];
728                         for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
729                                 float const alpha = float (op[3]) / 255;
730
731                                 /* Convert sRGB to XYZ; op is BGRA.  First, input gamma LUT */
732                                 double const r = lut_in[op[red]];
733                                 double const g = lut_in[op[1]];
734                                 double const b = lut_in[op[blue]];
735
736                                 /* RGB to XYZ, including Bradford transform and DCI companding */
737                                 double const x = max(0.0, min(1.0, r * fast_matrix[0] + g * fast_matrix[1] + b * fast_matrix[2]));
738                                 double const y = max(0.0, min(1.0, r * fast_matrix[3] + g * fast_matrix[4] + b * fast_matrix[5]));
739                                 double const z = max(0.0, min(1.0, r * fast_matrix[6] + g * fast_matrix[7] + b * fast_matrix[8]));
740
741                                 /* Out gamma LUT and blend */
742                                 tp[0] = lrint(lut_out[lrint(x * 65535)] * 65535) * alpha + tp[0] * (1 - alpha);
743                                 tp[1] = lrint(lut_out[lrint(y * 65535)] * 65535) * alpha + tp[1] * (1 - alpha);
744                                 tp[2] = lrint(lut_out[lrint(z * 65535)] * 65535) * alpha + tp[2] * (1 - alpha);
745
746                                 tp += this_bpp / 2;
747                                 op += other_bpp;
748                         }
749                 }
750                 break;
751         }
752         case AV_PIX_FMT_YUV420P:
753         {
754                 auto yuv = other->convert_pixel_format (dcp::YUVToRGB::REC709, _pixel_format, Alignment::COMPACT, false);
755                 dcp::Size const ts = size();
756                 dcp::Size const os = yuv->size();
757                 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
758                         int const hty = ty / 2;
759                         int const hoy = oy / 2;
760                         uint8_t* tY = data()[0] + (ty * stride()[0]) + start_tx;
761                         uint8_t* tU = data()[1] + (hty * stride()[1]) + start_tx / 2;
762                         uint8_t* tV = data()[2] + (hty * stride()[2]) + start_tx / 2;
763                         uint8_t* oY = yuv->data()[0] + (oy * yuv->stride()[0]) + start_ox;
764                         uint8_t* oU = yuv->data()[1] + (hoy * yuv->stride()[1]) + start_ox / 2;
765                         uint8_t* oV = yuv->data()[2] + (hoy * yuv->stride()[2]) + start_ox / 2;
766                         uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
767                         for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
768                                 float const a = float(alpha[3]) / 255;
769                                 *tY = *oY * a + *tY * (1 - a);
770                                 *tU = *oU * a + *tU * (1 - a);
771                                 *tV = *oV * a + *tV * (1 - a);
772                                 ++tY;
773                                 ++oY;
774                                 if (tx % 2) {
775                                         ++tU;
776                                         ++tV;
777                                 }
778                                 if (ox % 2) {
779                                         ++oU;
780                                         ++oV;
781                                 }
782                                 alpha += 4;
783                         }
784                 }
785                 break;
786         }
787         case AV_PIX_FMT_YUV420P10:
788         {
789                 auto yuv = other->convert_pixel_format (dcp::YUVToRGB::REC709, _pixel_format, Alignment::COMPACT, false);
790                 dcp::Size const ts = size();
791                 dcp::Size const os = yuv->size();
792                 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
793                         int const hty = ty / 2;
794                         int const hoy = oy / 2;
795                         uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
796                         uint16_t* tU = ((uint16_t *) (data()[1] + (hty * stride()[1]))) + start_tx / 2;
797                         uint16_t* tV = ((uint16_t *) (data()[2] + (hty * stride()[2]))) + start_tx / 2;
798                         uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
799                         uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (hoy * yuv->stride()[1]))) + start_ox / 2;
800                         uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (hoy * yuv->stride()[2]))) + start_ox / 2;
801                         uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
802                         for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
803                                 float const a = float(alpha[3]) / 255;
804                                 *tY = *oY * a + *tY * (1 - a);
805                                 *tU = *oU * a + *tU * (1 - a);
806                                 *tV = *oV * a + *tV * (1 - a);
807                                 ++tY;
808                                 ++oY;
809                                 if (tx % 2) {
810                                         ++tU;
811                                         ++tV;
812                                 }
813                                 if (ox % 2) {
814                                         ++oU;
815                                         ++oV;
816                                 }
817                                 alpha += 4;
818                         }
819                 }
820                 break;
821         }
822         case AV_PIX_FMT_YUV422P10LE:
823         {
824                 auto yuv = other->convert_pixel_format (dcp::YUVToRGB::REC709, _pixel_format, Alignment::COMPACT, false);
825                 dcp::Size const ts = size();
826                 dcp::Size const os = yuv->size();
827                 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
828                         uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
829                         uint16_t* tU = ((uint16_t *) (data()[1] + (ty * stride()[1]))) + start_tx / 2;
830                         uint16_t* tV = ((uint16_t *) (data()[2] + (ty * stride()[2]))) + start_tx / 2;
831                         uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
832                         uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (oy * yuv->stride()[1]))) + start_ox / 2;
833                         uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (oy * yuv->stride()[2]))) + start_ox / 2;
834                         uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
835                         for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
836                                 float const a = float(alpha[3]) / 255;
837                                 *tY = *oY * a + *tY * (1 - a);
838                                 *tU = *oU * a + *tU * (1 - a);
839                                 *tV = *oV * a + *tV * (1 - a);
840                                 ++tY;
841                                 ++oY;
842                                 if (tx % 2) {
843                                         ++tU;
844                                         ++tV;
845                                 }
846                                 if (ox % 2) {
847                                         ++oU;
848                                         ++oV;
849                                 }
850                                 alpha += 4;
851                         }
852                 }
853                 break;
854         }
855         default:
856                 throw PixelFormatError ("alpha_blend()", _pixel_format);
857         }
858 }
859
860
861 void
862 Image::copy (shared_ptr<const Image> other, Position<int> position)
863 {
864         /* Only implemented for RGB24 onto RGB24 so far */
865         DCPOMATIC_ASSERT (_pixel_format == AV_PIX_FMT_RGB24 && other->pixel_format() == AV_PIX_FMT_RGB24);
866         DCPOMATIC_ASSERT (position.x >= 0 && position.y >= 0);
867
868         int const N = min (position.x + other->size().width, size().width) - position.x;
869         for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
870                 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
871                 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
872                 memcpy (tp, op, N * 3);
873         }
874 }
875
876
877 void
878 Image::read_from_socket (shared_ptr<Socket> socket)
879 {
880         for (int i = 0; i < planes(); ++i) {
881                 uint8_t* p = data()[i];
882                 int const lines = sample_size(i).height;
883                 for (int y = 0; y < lines; ++y) {
884                         socket->read (p, line_size()[i]);
885                         p += stride()[i];
886                 }
887         }
888 }
889
890
891 void
892 Image::write_to_socket (shared_ptr<Socket> socket) const
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->write (p, line_size()[i]);
899                         p += stride()[i];
900                 }
901         }
902 }
903
904
905 float
906 Image::bytes_per_pixel (int c) const
907 {
908         auto d = av_pix_fmt_desc_get(_pixel_format);
909         if (!d) {
910                 throw PixelFormatError ("bytes_per_pixel()", _pixel_format);
911         }
912
913         if (c >= planes()) {
914                 return 0;
915         }
916
917         float bpp[4] = { 0, 0, 0, 0 };
918
919 #ifdef DCPOMATIC_HAVE_AVCOMPONENTDESCRIPTOR_DEPTH_MINUS1
920         bpp[0] = floor ((d->comp[0].depth_minus1 + 8) / 8);
921         if (d->nb_components > 1) {
922                 bpp[1] = floor ((d->comp[1].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
923         }
924         if (d->nb_components > 2) {
925                 bpp[2] = floor ((d->comp[2].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
926         }
927         if (d->nb_components > 3) {
928                 bpp[3] = floor ((d->comp[3].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
929         }
930 #else
931         bpp[0] = floor ((d->comp[0].depth + 7) / 8);
932         if (d->nb_components > 1) {
933                 bpp[1] = floor ((d->comp[1].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
934         }
935         if (d->nb_components > 2) {
936                 bpp[2] = floor ((d->comp[2].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
937         }
938         if (d->nb_components > 3) {
939                 bpp[3] = floor ((d->comp[3].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
940         }
941 #endif
942
943         if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
944                 /* Not planar; sum them up */
945                 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
946         }
947
948         return bpp[c];
949 }
950
951
952 /** Construct a Image of a given size and format, allocating memory
953  *  as required.
954  *
955  *  @param p Pixel format.
956  *  @param s Size in pixels.
957  *  @param alignment PADDED to make each row of this image aligned to a ALIGNMENT-byte boundary, otherwise COMPACT.
958  */
959 Image::Image (AVPixelFormat p, dcp::Size s, Alignment alignment)
960         : _size (s)
961         , _pixel_format (p)
962         , _alignment (alignment)
963 {
964         allocate ();
965 }
966
967
968 void
969 Image::allocate ()
970 {
971         _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
972         _data[0] = _data[1] = _data[2] = _data[3] = 0;
973
974         _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
975         _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
976
977         _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
978         _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
979
980         auto stride_round_up = [](int stride, int t) {
981                 int const a = stride + (t - 1);
982                 return a - (a % t);
983         };
984
985         for (int i = 0; i < planes(); ++i) {
986                 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
987                 _stride[i] = stride_round_up (_line_size[i], _alignment == Alignment::PADDED ? ALIGNMENT : 1);
988
989                 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
990                    uses a 16-byte fetch to read three bytes (R/G/B) of image data.
991                    Hence on the last pixel of the last line it reads over the end of
992                    the actual data by 1 byte.  If the width of an image is a multiple
993                    of the stride alignment there will be no padding at the end of image lines.
994                    OS X crashes on this illegal read, though other operating systems don't
995                    seem to mind.  The nasty + 1 in this malloc makes sure there is always a byte
996                    for that instruction to read safely.
997
998                    Further to the above, valgrind is now telling me that ff_rgb24ToY_ssse3
999                    over-reads by more then _avx.  I can't follow the code to work out how much,
1000                    so I'll just over-allocate by ALIGNMENT bytes and have done with it.  Empirical
1001                    testing suggests that it works.
1002
1003                    In addition to these concerns, we may read/write as much as a whole extra line
1004                    at the end of each plane in cases where we are messing with offsets in order to
1005                    do pad or crop.  To solve this we over-allocate by an extra _stride[i] bytes.
1006
1007                    As an example: we may write to images starting at an offset so we get some padding.
1008                    Hence we want to write in the following pattern:
1009
1010                    block start   write start                                  line end
1011                    |..(padding)..|<------line-size------------->|..(padding)..|
1012                    |..(padding)..|<------line-size------------->|..(padding)..|
1013                    |..(padding)..|<------line-size------------->|..(padding)..|
1014
1015                    where line-size is of the smaller (inter_size) image and the full padded line length is that of
1016                    out_size.  To get things to work we have to tell FFmpeg that the stride is that of out_size.
1017                    However some parts of FFmpeg (notably rgb48Toxyz12 in swscale.c) process data for the full
1018                    specified *stride*.  This does not matter until we get to the last line:
1019
1020                    block start   write start                                  line end
1021                    |..(padding)..|<------line-size------------->|XXXwrittenXXX|
1022                    |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXX|
1023                    |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXXXXXwrittenXXX
1024                                                                                ^^^^ out of bounds
1025                 */
1026                 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * (sample_size(i).height + 1) + ALIGNMENT);
1027 #if HAVE_VALGRIND_MEMCHECK_H
1028                 /* The data between the end of the line size and the stride is undefined but processed by
1029                    libswscale, causing lots of valgrind errors.  Mark it all defined to quell these errors.
1030                 */
1031                 VALGRIND_MAKE_MEM_DEFINED (_data[i], _stride[i] * (sample_size(i).height + 1) + ALIGNMENT);
1032 #endif
1033         }
1034 }
1035
1036
1037 Image::Image (Image const & other)
1038         : std::enable_shared_from_this<Image>(other)
1039         , _size (other._size)
1040         , _pixel_format (other._pixel_format)
1041         , _alignment (other._alignment)
1042 {
1043         allocate ();
1044
1045         for (int i = 0; i < planes(); ++i) {
1046                 uint8_t* p = _data[i];
1047                 uint8_t* q = other._data[i];
1048                 int const lines = sample_size(i).height;
1049                 for (int j = 0; j < lines; ++j) {
1050                         memcpy (p, q, _line_size[i]);
1051                         p += stride()[i];
1052                         q += other.stride()[i];
1053                 }
1054         }
1055 }
1056
1057
1058 Image::Image (AVFrame const * frame, Alignment alignment)
1059         : _size (frame->width, frame->height)
1060         , _pixel_format (static_cast<AVPixelFormat>(frame->format))
1061         , _alignment (alignment)
1062 {
1063         DCPOMATIC_ASSERT (_pixel_format != AV_PIX_FMT_NONE);
1064
1065         allocate ();
1066
1067         for (int i = 0; i < planes(); ++i) {
1068                 uint8_t* p = _data[i];
1069                 uint8_t* q = frame->data[i];
1070                 int const lines = sample_size(i).height;
1071                 for (int j = 0; j < lines; ++j) {
1072                         memcpy (p, q, _line_size[i]);
1073                         p += stride()[i];
1074                         /* AVFrame's linesize is what we call `stride' */
1075                         q += frame->linesize[i];
1076                 }
1077         }
1078 }
1079
1080
1081 Image::Image (shared_ptr<const Image> other, Alignment alignment)
1082         : _size (other->_size)
1083         , _pixel_format (other->_pixel_format)
1084         , _alignment (alignment)
1085 {
1086         allocate ();
1087
1088         for (int i = 0; i < planes(); ++i) {
1089                 DCPOMATIC_ASSERT (line_size()[i] == other->line_size()[i]);
1090                 uint8_t* p = _data[i];
1091                 uint8_t* q = other->data()[i];
1092                 int const lines = sample_size(i).height;
1093                 for (int j = 0; j < lines; ++j) {
1094                         memcpy (p, q, line_size()[i]);
1095                         p += stride()[i];
1096                         q += other->stride()[i];
1097                 }
1098         }
1099 }
1100
1101
1102 Image&
1103 Image::operator= (Image const & other)
1104 {
1105         if (this == &other) {
1106                 return *this;
1107         }
1108
1109         Image tmp (other);
1110         swap (tmp);
1111         return *this;
1112 }
1113
1114
1115 void
1116 Image::swap (Image & other)
1117 {
1118         std::swap (_size, other._size);
1119         std::swap (_pixel_format, other._pixel_format);
1120
1121         for (int i = 0; i < 4; ++i) {
1122                 std::swap (_data[i], other._data[i]);
1123                 std::swap (_line_size[i], other._line_size[i]);
1124                 std::swap (_stride[i], other._stride[i]);
1125         }
1126
1127         std::swap (_alignment, other._alignment);
1128 }
1129
1130
1131 Image::~Image ()
1132 {
1133         for (int i = 0; i < planes(); ++i) {
1134                 av_free (_data[i]);
1135         }
1136
1137         av_free (_data);
1138         av_free (_line_size);
1139         av_free (_stride);
1140 }
1141
1142
1143 uint8_t * const *
1144 Image::data () const
1145 {
1146         return _data;
1147 }
1148
1149
1150 int const *
1151 Image::line_size () const
1152 {
1153         return _line_size;
1154 }
1155
1156
1157 int const *
1158 Image::stride () const
1159 {
1160         return _stride;
1161 }
1162
1163
1164 dcp::Size
1165 Image::size () const
1166 {
1167         return _size;
1168 }
1169
1170
1171 Image::Alignment
1172 Image::alignment () const
1173 {
1174         return _alignment;
1175 }
1176
1177
1178 PositionImage
1179 merge (list<PositionImage> images, Image::Alignment alignment)
1180 {
1181         if (images.empty ()) {
1182                 return {};
1183         }
1184
1185         if (images.size() == 1) {
1186                 images.front().image = Image::ensure_alignment(images.front().image, alignment);
1187                 return images.front();
1188         }
1189
1190         dcpomatic::Rect<int> all (images.front().position, images.front().image->size().width, images.front().image->size().height);
1191         for (auto const& i: images) {
1192                 all.extend (dcpomatic::Rect<int>(i.position, i.image->size().width, i.image->size().height));
1193         }
1194
1195         auto merged = make_shared<Image>(images.front().image->pixel_format(), dcp::Size(all.width, all.height), alignment);
1196         merged->make_transparent ();
1197         for (auto const& i: images) {
1198                 merged->alpha_blend (i.image, i.position - all.position());
1199         }
1200
1201         return PositionImage (merged, all.position ());
1202 }
1203
1204
1205 bool
1206 operator== (Image const & a, Image const & b)
1207 {
1208         if (a.planes() != b.planes() || a.pixel_format() != b.pixel_format() || a.alignment() != b.alignment()) {
1209                 return false;
1210         }
1211
1212         for (int c = 0; c < a.planes(); ++c) {
1213                 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]) {
1214                         return false;
1215                 }
1216
1217                 uint8_t* p = a.data()[c];
1218                 uint8_t* q = b.data()[c];
1219                 int const lines = a.sample_size(c).height;
1220                 for (int y = 0; y < lines; ++y) {
1221                         if (memcmp (p, q, a.line_size()[c]) != 0) {
1222                                 return false;
1223                         }
1224
1225                         p += a.stride()[c];
1226                         q += b.stride()[c];
1227                 }
1228         }
1229
1230         return true;
1231 }
1232
1233
1234 /** Fade the image.
1235  *  @param f Amount to fade by; 0 is black, 1 is no fade.
1236  */
1237 void
1238 Image::fade (float f)
1239 {
1240         /* U/V black value for 8-bit colour */
1241         static int const eight_bit_uv =    (1 << 7) - 1;
1242         /* U/V black value for 10-bit colour */
1243         static uint16_t const ten_bit_uv = (1 << 9) - 1;
1244
1245         switch (_pixel_format) {
1246         case AV_PIX_FMT_YUV420P:
1247         {
1248                 /* Y */
1249                 uint8_t* p = data()[0];
1250                 int const lines = sample_size(0).height;
1251                 for (int y = 0; y < lines; ++y) {
1252                         uint8_t* q = p;
1253                         for (int x = 0; x < line_size()[0]; ++x) {
1254                                 *q = int(float(*q) * f);
1255                                 ++q;
1256                         }
1257                         p += stride()[0];
1258                 }
1259
1260                 /* U, V */
1261                 for (int c = 1; c < 3; ++c) {
1262                         uint8_t* p = data()[c];
1263                         int const lines = sample_size(c).height;
1264                         for (int y = 0; y < lines; ++y) {
1265                                 uint8_t* q = p;
1266                                 for (int x = 0; x < line_size()[c]; ++x) {
1267                                         *q = eight_bit_uv + int((int(*q) - eight_bit_uv) * f);
1268                                         ++q;
1269                                 }
1270                                 p += stride()[c];
1271                         }
1272                 }
1273
1274                 break;
1275         }
1276
1277         case AV_PIX_FMT_RGB24:
1278         {
1279                 /* 8-bit */
1280                 uint8_t* p = data()[0];
1281                 int const lines = sample_size(0).height;
1282                 for (int y = 0; y < lines; ++y) {
1283                         uint8_t* q = p;
1284                         for (int x = 0; x < line_size()[0]; ++x) {
1285                                 *q = int (float (*q) * f);
1286                                 ++q;
1287                         }
1288                         p += stride()[0];
1289                 }
1290                 break;
1291         }
1292
1293         case AV_PIX_FMT_XYZ12LE:
1294         case AV_PIX_FMT_RGB48LE:
1295                 /* 16-bit little-endian */
1296                 for (int c = 0; c < 3; ++c) {
1297                         int const stride_pixels = stride()[c] / 2;
1298                         int const line_size_pixels = line_size()[c] / 2;
1299                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1300                         int const lines = sample_size(c).height;
1301                         for (int y = 0; y < lines; ++y) {
1302                                 uint16_t* q = p;
1303                                 for (int x = 0; x < line_size_pixels; ++x) {
1304                                         *q = int (float (*q) * f);
1305                                         ++q;
1306                                 }
1307                                 p += stride_pixels;
1308                         }
1309                 }
1310                 break;
1311
1312         case AV_PIX_FMT_YUV422P10LE:
1313         {
1314                 /* Y */
1315                 {
1316                         int const stride_pixels = stride()[0] / 2;
1317                         int const line_size_pixels = line_size()[0] / 2;
1318                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[0]);
1319                         int const lines = sample_size(0).height;
1320                         for (int y = 0; y < lines; ++y) {
1321                                 uint16_t* q = p;
1322                                 for (int x = 0; x < line_size_pixels; ++x) {
1323                                         *q = int(float(*q) * f);
1324                                         ++q;
1325                                 }
1326                                 p += stride_pixels;
1327                         }
1328                 }
1329
1330                 /* U, V */
1331                 for (int c = 1; c < 3; ++c) {
1332                         int const stride_pixels = stride()[c] / 2;
1333                         int const line_size_pixels = line_size()[c] / 2;
1334                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1335                         int const lines = sample_size(c).height;
1336                         for (int y = 0; y < lines; ++y) {
1337                                 uint16_t* q = p;
1338                                 for (int x = 0; x < line_size_pixels; ++x) {
1339                                         *q = ten_bit_uv + int((int(*q) - ten_bit_uv) * f);
1340                                         ++q;
1341                                 }
1342                                 p += stride_pixels;
1343                         }
1344                 }
1345                 break;
1346
1347         }
1348
1349         default:
1350                 throw PixelFormatError ("fade()", _pixel_format);
1351         }
1352 }
1353
1354
1355 shared_ptr<const Image>
1356 Image::ensure_alignment (shared_ptr<const Image> image, Image::Alignment alignment)
1357 {
1358         if (image->alignment() == alignment) {
1359                 return image;
1360         }
1361
1362         return make_shared<Image>(image, alignment);
1363 }
1364
1365
1366 size_t
1367 Image::memory_used () const
1368 {
1369         size_t m = 0;
1370         for (int i = 0; i < planes(); ++i) {
1371                 m += _stride[i] * sample_size(i).height;
1372         }
1373         return m;
1374 }
1375
1376
1377 void
1378 Image::video_range_to_full_range ()
1379 {
1380         switch (_pixel_format) {
1381         case AV_PIX_FMT_RGB24:
1382         {
1383                 float const factor = 256.0 / 219.0;
1384                 uint8_t* p = data()[0];
1385                 int const lines = sample_size(0).height;
1386                 for (int y = 0; y < lines; ++y) {
1387                         uint8_t* q = p;
1388                         for (int x = 0; x < line_size()[0]; ++x) {
1389                                 *q = clamp(lrintf((*q - 16) * factor), 0L, 255L);
1390                                 ++q;
1391                         }
1392                         p += stride()[0];
1393                 }
1394                 break;
1395         }
1396         case AV_PIX_FMT_RGB48LE:
1397         {
1398                 float const factor = 65536.0 / 56064.0;
1399                 uint16_t* p = reinterpret_cast<uint16_t*>(data()[0]);
1400                 int const lines = sample_size(0).height;
1401                 for (int y = 0; y < lines; ++y) {
1402                         uint16_t* q = p;
1403                         int const line_size_pixels = line_size()[0] / 2;
1404                         for (int x = 0; x < line_size_pixels; ++x) {
1405                                 *q = clamp(lrintf((*q - 4096) * factor), 0L, 65535L);
1406                                 ++q;
1407                         }
1408                         p += stride()[0] / 2;
1409                 }
1410                 break;
1411         }
1412         case AV_PIX_FMT_GBRP12LE:
1413         {
1414                 float const factor = 4096.0 / 3504.0;
1415                 for (int c = 0; c < 3; ++c) {
1416                         uint16_t* p = reinterpret_cast<uint16_t*>(data()[c]);
1417                         int const lines = sample_size(c).height;
1418                         for (int y = 0; y < lines; ++y) {
1419                                 uint16_t* q = p;
1420                                 int const line_size_pixels = line_size()[c] / 2;
1421                                 for (int x = 0; x < line_size_pixels; ++x) {
1422                                         *q = clamp(lrintf((*q - 256) * factor), 0L, 4095L);
1423                                         ++q;
1424                                 }
1425                         }
1426                 }
1427                 break;
1428         }
1429         default:
1430                 throw PixelFormatError ("video_range_to_full_range()", _pixel_format);
1431         }
1432 }
1433