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