Cleanup: move stride_round_up into the only place it is used.
[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         auto stride_round_up = [](int stride, int t) {
976                 int const a = stride + (t - 1);
977                 return a - (a % t);
978         };
979
980         for (int i = 0; i < planes(); ++i) {
981                 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
982                 _stride[i] = stride_round_up (_line_size[i], _alignment == Alignment::PADDED ? ALIGNMENT : 1);
983
984                 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
985                    uses a 16-byte fetch to read three bytes (R/G/B) of image data.
986                    Hence on the last pixel of the last line it reads over the end of
987                    the actual data by 1 byte.  If the width of an image is a multiple
988                    of the stride alignment there will be no padding at the end of image lines.
989                    OS X crashes on this illegal read, though other operating systems don't
990                    seem to mind.  The nasty + 1 in this malloc makes sure there is always a byte
991                    for that instruction to read safely.
992
993                    Further to the above, valgrind is now telling me that ff_rgb24ToY_ssse3
994                    over-reads by more then _avx.  I can't follow the code to work out how much,
995                    so I'll just over-allocate by ALIGNMENT bytes and have done with it.  Empirical
996                    testing suggests that it works.
997
998                    In addition to these concerns, we may read/write as much as a whole extra line
999                    at the end of each plane in cases where we are messing with offsets in order to
1000                    do pad or crop.  To solve this we over-allocate by an extra _stride[i] bytes.
1001
1002                    As an example: we may write to images starting at an offset so we get some padding.
1003                    Hence we want to write in the following pattern:
1004
1005                    block start   write start                                  line end
1006                    |..(padding)..|<------line-size------------->|..(padding)..|
1007                    |..(padding)..|<------line-size------------->|..(padding)..|
1008                    |..(padding)..|<------line-size------------->|..(padding)..|
1009
1010                    where line-size is of the smaller (inter_size) image and the full padded line length is that of
1011                    out_size.  To get things to work we have to tell FFmpeg that the stride is that of out_size.
1012                    However some parts of FFmpeg (notably rgb48Toxyz12 in swscale.c) process data for the full
1013                    specified *stride*.  This does not matter until we get to the last line:
1014
1015                    block start   write start                                  line end
1016                    |..(padding)..|<------line-size------------->|XXXwrittenXXX|
1017                    |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXX|
1018                    |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXXXXXwrittenXXX
1019                                                                                ^^^^ out of bounds
1020                 */
1021                 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * (sample_size(i).height + 1) + ALIGNMENT);
1022 #if HAVE_VALGRIND_MEMCHECK_H
1023                 /* The data between the end of the line size and the stride is undefined but processed by
1024                    libswscale, causing lots of valgrind errors.  Mark it all defined to quell these errors.
1025                 */
1026                 VALGRIND_MAKE_MEM_DEFINED (_data[i], _stride[i] * (sample_size(i).height + 1) + ALIGNMENT);
1027 #endif
1028         }
1029 }
1030
1031
1032 Image::Image (Image const & other)
1033         : std::enable_shared_from_this<Image>(other)
1034         , _size (other._size)
1035         , _pixel_format (other._pixel_format)
1036         , _alignment (other._alignment)
1037 {
1038         allocate ();
1039
1040         for (int i = 0; i < planes(); ++i) {
1041                 uint8_t* p = _data[i];
1042                 uint8_t* q = other._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                         q += other.stride()[i];
1048                 }
1049         }
1050 }
1051
1052
1053 Image::Image (AVFrame const * frame, Alignment alignment)
1054         : _size (frame->width, frame->height)
1055         , _pixel_format (static_cast<AVPixelFormat>(frame->format))
1056         , _alignment (alignment)
1057 {
1058         DCPOMATIC_ASSERT (_pixel_format != AV_PIX_FMT_NONE);
1059
1060         allocate ();
1061
1062         for (int i = 0; i < planes(); ++i) {
1063                 uint8_t* p = _data[i];
1064                 uint8_t* q = frame->data[i];
1065                 int const lines = sample_size(i).height;
1066                 for (int j = 0; j < lines; ++j) {
1067                         memcpy (p, q, _line_size[i]);
1068                         p += stride()[i];
1069                         /* AVFrame's linesize is what we call `stride' */
1070                         q += frame->linesize[i];
1071                 }
1072         }
1073 }
1074
1075
1076 Image::Image (shared_ptr<const Image> other, Alignment alignment)
1077         : _size (other->_size)
1078         , _pixel_format (other->_pixel_format)
1079         , _alignment (alignment)
1080 {
1081         allocate ();
1082
1083         for (int i = 0; i < planes(); ++i) {
1084                 DCPOMATIC_ASSERT (line_size()[i] == other->line_size()[i]);
1085                 uint8_t* p = _data[i];
1086                 uint8_t* q = other->data()[i];
1087                 int const lines = sample_size(i).height;
1088                 for (int j = 0; j < lines; ++j) {
1089                         memcpy (p, q, line_size()[i]);
1090                         p += stride()[i];
1091                         q += other->stride()[i];
1092                 }
1093         }
1094 }
1095
1096
1097 Image&
1098 Image::operator= (Image const & other)
1099 {
1100         if (this == &other) {
1101                 return *this;
1102         }
1103
1104         Image tmp (other);
1105         swap (tmp);
1106         return *this;
1107 }
1108
1109
1110 void
1111 Image::swap (Image & other)
1112 {
1113         std::swap (_size, other._size);
1114         std::swap (_pixel_format, other._pixel_format);
1115
1116         for (int i = 0; i < 4; ++i) {
1117                 std::swap (_data[i], other._data[i]);
1118                 std::swap (_line_size[i], other._line_size[i]);
1119                 std::swap (_stride[i], other._stride[i]);
1120         }
1121
1122         std::swap (_alignment, other._alignment);
1123 }
1124
1125
1126 Image::~Image ()
1127 {
1128         for (int i = 0; i < planes(); ++i) {
1129                 av_free (_data[i]);
1130         }
1131
1132         av_free (_data);
1133         av_free (_line_size);
1134         av_free (_stride);
1135 }
1136
1137
1138 uint8_t * const *
1139 Image::data () const
1140 {
1141         return _data;
1142 }
1143
1144
1145 int const *
1146 Image::line_size () const
1147 {
1148         return _line_size;
1149 }
1150
1151
1152 int const *
1153 Image::stride () const
1154 {
1155         return _stride;
1156 }
1157
1158
1159 dcp::Size
1160 Image::size () const
1161 {
1162         return _size;
1163 }
1164
1165
1166 Image::Alignment
1167 Image::alignment () const
1168 {
1169         return _alignment;
1170 }
1171
1172
1173 PositionImage
1174 merge (list<PositionImage> images, Image::Alignment alignment)
1175 {
1176         if (images.empty ()) {
1177                 return {};
1178         }
1179
1180         if (images.size() == 1) {
1181                 images.front().image = Image::ensure_alignment(images.front().image, alignment);
1182                 return images.front();
1183         }
1184
1185         dcpomatic::Rect<int> all (images.front().position, images.front().image->size().width, images.front().image->size().height);
1186         for (auto const& i: images) {
1187                 all.extend (dcpomatic::Rect<int>(i.position, i.image->size().width, i.image->size().height));
1188         }
1189
1190         auto merged = make_shared<Image>(images.front().image->pixel_format(), dcp::Size(all.width, all.height), alignment);
1191         merged->make_transparent ();
1192         for (auto const& i: images) {
1193                 merged->alpha_blend (i.image, i.position - all.position());
1194         }
1195
1196         return PositionImage (merged, all.position ());
1197 }
1198
1199
1200 bool
1201 operator== (Image const & a, Image const & b)
1202 {
1203         if (a.planes() != b.planes() || a.pixel_format() != b.pixel_format() || a.alignment() != b.alignment()) {
1204                 return false;
1205         }
1206
1207         for (int c = 0; c < a.planes(); ++c) {
1208                 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]) {
1209                         return false;
1210                 }
1211
1212                 uint8_t* p = a.data()[c];
1213                 uint8_t* q = b.data()[c];
1214                 int const lines = a.sample_size(c).height;
1215                 for (int y = 0; y < lines; ++y) {
1216                         if (memcmp (p, q, a.line_size()[c]) != 0) {
1217                                 return false;
1218                         }
1219
1220                         p += a.stride()[c];
1221                         q += b.stride()[c];
1222                 }
1223         }
1224
1225         return true;
1226 }
1227
1228
1229 /** Fade the image.
1230  *  @param f Amount to fade by; 0 is black, 1 is no fade.
1231  */
1232 void
1233 Image::fade (float f)
1234 {
1235         /* U/V black value for 8-bit colour */
1236         static int const eight_bit_uv =    (1 << 7) - 1;
1237         /* U/V black value for 10-bit colour */
1238         static uint16_t const ten_bit_uv = (1 << 9) - 1;
1239
1240         switch (_pixel_format) {
1241         case AV_PIX_FMT_YUV420P:
1242         {
1243                 /* Y */
1244                 uint8_t* p = data()[0];
1245                 int const lines = sample_size(0).height;
1246                 for (int y = 0; y < lines; ++y) {
1247                         uint8_t* q = p;
1248                         for (int x = 0; x < line_size()[0]; ++x) {
1249                                 *q = int(float(*q) * f);
1250                                 ++q;
1251                         }
1252                         p += stride()[0];
1253                 }
1254
1255                 /* U, V */
1256                 for (int c = 1; c < 3; ++c) {
1257                         uint8_t* p = data()[c];
1258                         int const lines = sample_size(c).height;
1259                         for (int y = 0; y < lines; ++y) {
1260                                 uint8_t* q = p;
1261                                 for (int x = 0; x < line_size()[c]; ++x) {
1262                                         *q = eight_bit_uv + int((int(*q) - eight_bit_uv) * f);
1263                                         ++q;
1264                                 }
1265                                 p += stride()[c];
1266                         }
1267                 }
1268
1269                 break;
1270         }
1271
1272         case AV_PIX_FMT_RGB24:
1273         {
1274                 /* 8-bit */
1275                 uint8_t* p = data()[0];
1276                 int const lines = sample_size(0).height;
1277                 for (int y = 0; y < lines; ++y) {
1278                         uint8_t* q = p;
1279                         for (int x = 0; x < line_size()[0]; ++x) {
1280                                 *q = int (float (*q) * f);
1281                                 ++q;
1282                         }
1283                         p += stride()[0];
1284                 }
1285                 break;
1286         }
1287
1288         case AV_PIX_FMT_XYZ12LE:
1289         case AV_PIX_FMT_RGB48LE:
1290                 /* 16-bit little-endian */
1291                 for (int c = 0; c < 3; ++c) {
1292                         int const stride_pixels = stride()[c] / 2;
1293                         int const line_size_pixels = line_size()[c] / 2;
1294                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1295                         int const lines = sample_size(c).height;
1296                         for (int y = 0; y < lines; ++y) {
1297                                 uint16_t* q = p;
1298                                 for (int x = 0; x < line_size_pixels; ++x) {
1299                                         *q = int (float (*q) * f);
1300                                         ++q;
1301                                 }
1302                                 p += stride_pixels;
1303                         }
1304                 }
1305                 break;
1306
1307         case AV_PIX_FMT_YUV422P10LE:
1308         {
1309                 /* Y */
1310                 {
1311                         int const stride_pixels = stride()[0] / 2;
1312                         int const line_size_pixels = line_size()[0] / 2;
1313                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[0]);
1314                         int const lines = sample_size(0).height;
1315                         for (int y = 0; y < lines; ++y) {
1316                                 uint16_t* q = p;
1317                                 for (int x = 0; x < line_size_pixels; ++x) {
1318                                         *q = int(float(*q) * f);
1319                                         ++q;
1320                                 }
1321                                 p += stride_pixels;
1322                         }
1323                 }
1324
1325                 /* U, V */
1326                 for (int c = 1; c < 3; ++c) {
1327                         int const stride_pixels = stride()[c] / 2;
1328                         int const line_size_pixels = line_size()[c] / 2;
1329                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1330                         int const lines = sample_size(c).height;
1331                         for (int y = 0; y < lines; ++y) {
1332                                 uint16_t* q = p;
1333                                 for (int x = 0; x < line_size_pixels; ++x) {
1334                                         *q = ten_bit_uv + int((int(*q) - ten_bit_uv) * f);
1335                                         ++q;
1336                                 }
1337                                 p += stride_pixels;
1338                         }
1339                 }
1340                 break;
1341
1342         }
1343
1344         default:
1345                 throw PixelFormatError ("fade()", _pixel_format);
1346         }
1347 }
1348
1349
1350 shared_ptr<const Image>
1351 Image::ensure_alignment (shared_ptr<const Image> image, Image::Alignment alignment)
1352 {
1353         if (image->alignment() == alignment) {
1354                 return image;
1355         }
1356
1357         return make_shared<Image>(image, alignment);
1358 }
1359
1360
1361 size_t
1362 Image::memory_used () const
1363 {
1364         size_t m = 0;
1365         for (int i = 0; i < planes(); ++i) {
1366                 m += _stride[i] * sample_size(i).height;
1367         }
1368         return m;
1369 }
1370
1371
1372 class Memory
1373 {
1374 public:
1375         Memory ()
1376                 : data(0)
1377                 , size(0)
1378         {}
1379
1380         ~Memory ()
1381         {
1382                 free (data);
1383         }
1384
1385         uint8_t* data;
1386         size_t size;
1387 };
1388
1389
1390 static void
1391 png_write_data (png_structp png_ptr, png_bytep data, png_size_t length)
1392 {
1393         auto mem = reinterpret_cast<Memory*>(png_get_io_ptr(png_ptr));
1394         size_t size = mem->size + length;
1395
1396         if (mem->data) {
1397                 mem->data = reinterpret_cast<uint8_t*>(realloc(mem->data, size));
1398         } else {
1399                 mem->data = reinterpret_cast<uint8_t*>(malloc(size));
1400         }
1401
1402         if (!mem->data) {
1403                 throw EncodeError (N_("could not allocate memory for PNG"));
1404         }
1405
1406         memcpy (mem->data + mem->size, data, length);
1407         mem->size += length;
1408 }
1409
1410
1411 static void
1412 png_flush (png_structp)
1413 {
1414
1415 }
1416
1417
1418 static void
1419 png_error_fn (png_structp png_ptr, char const * message)
1420 {
1421         reinterpret_cast<Image*>(png_get_error_ptr(png_ptr))->png_error (message);
1422 }
1423
1424
1425 void
1426 Image::png_error (char const * message)
1427 {
1428         throw EncodeError (String::compose ("Error during PNG write: %1", message));
1429 }
1430
1431
1432 dcp::ArrayData
1433 Image::as_png () const
1434 {
1435         DCPOMATIC_ASSERT (bytes_per_pixel(0) == 4);
1436         DCPOMATIC_ASSERT (planes() == 1);
1437         if (pixel_format() != AV_PIX_FMT_RGBA) {
1438                 return convert_pixel_format(dcp::YUVToRGB::REC709, AV_PIX_FMT_RGBA, Image::Alignment::PADDED, false)->as_png();
1439         }
1440
1441         /* error handling? */
1442         png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, reinterpret_cast<void*>(const_cast<Image*>(this)), png_error_fn, 0);
1443         if (!png_ptr) {
1444                 throw EncodeError (N_("could not create PNG write struct"));
1445         }
1446
1447         Memory state;
1448
1449         png_set_write_fn (png_ptr, &state, png_write_data, png_flush);
1450
1451         png_infop info_ptr = png_create_info_struct(png_ptr);
1452         if (!info_ptr) {
1453                 png_destroy_write_struct (&png_ptr, &info_ptr);
1454                 throw EncodeError (N_("could not create PNG info struct"));
1455         }
1456
1457         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);
1458
1459         png_byte ** row_pointers = reinterpret_cast<png_byte **>(png_malloc(png_ptr, size().height * sizeof(png_byte *)));
1460         for (int i = 0; i < size().height; ++i) {
1461                 row_pointers[i] = (png_byte *) (data()[0] + i * stride()[0]);
1462         }
1463
1464         png_write_info (png_ptr, info_ptr);
1465         png_write_image (png_ptr, row_pointers);
1466         png_write_end (png_ptr, info_ptr);
1467
1468         png_destroy_write_struct (&png_ptr, &info_ptr);
1469         png_free (png_ptr, row_pointers);
1470
1471         return dcp::ArrayData (state.data, state.size);
1472 }
1473
1474
1475 void
1476 Image::video_range_to_full_range ()
1477 {
1478         switch (_pixel_format) {
1479         case AV_PIX_FMT_RGB24:
1480         {
1481                 float const factor = 256.0 / 219.0;
1482                 uint8_t* p = data()[0];
1483                 int const lines = sample_size(0).height;
1484                 for (int y = 0; y < lines; ++y) {
1485                         uint8_t* q = p;
1486                         for (int x = 0; x < line_size()[0]; ++x) {
1487                                 *q = clamp(lrintf((*q - 16) * factor), 0L, 255L);
1488                                 ++q;
1489                         }
1490                         p += stride()[0];
1491                 }
1492                 break;
1493         }
1494         case AV_PIX_FMT_RGB48LE:
1495         {
1496                 float const factor = 65536.0 / 56064.0;
1497                 uint16_t* p = reinterpret_cast<uint16_t*>(data()[0]);
1498                 int const lines = sample_size(0).height;
1499                 for (int y = 0; y < lines; ++y) {
1500                         uint16_t* q = p;
1501                         int const line_size_pixels = line_size()[0] / 2;
1502                         for (int x = 0; x < line_size_pixels; ++x) {
1503                                 *q = clamp(lrintf((*q - 4096) * factor), 0L, 65535L);
1504                                 ++q;
1505                         }
1506                         p += stride()[0] / 2;
1507                 }
1508                 break;
1509         }
1510         case AV_PIX_FMT_GBRP12LE:
1511         {
1512                 float const factor = 4096.0 / 3504.0;
1513                 for (int c = 0; c < 3; ++c) {
1514                         uint16_t* p = reinterpret_cast<uint16_t*>(data()[c]);
1515                         int const lines = sample_size(c).height;
1516                         for (int y = 0; y < lines; ++y) {
1517                                 uint16_t* q = p;
1518                                 int const line_size_pixels = line_size()[c] / 2;
1519                                 for (int x = 0; x < line_size_pixels; ++x) {
1520                                         *q = clamp(lrintf((*q - 256) * factor), 0L, 4095L);
1521                                         ++q;
1522                                 }
1523                         }
1524                 }
1525                 break;
1526         }
1527         default:
1528                 throw PixelFormatError ("video_range_to_full_range()", _pixel_format);
1529         }
1530 }
1531