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