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