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