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