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