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