03fe494736b92faff551a31860ff75924ecde1e6
[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         DCPOMATIC_ASSERT (_pixel_format != AV_PIX_FMT_NONE);
984
985         allocate ();
986
987         for (int i = 0; i < planes(); ++i) {
988                 uint8_t* p = _data[i];
989                 uint8_t* q = frame->data[i];
990                 int const lines = sample_size(i).height;
991                 for (int j = 0; j < lines; ++j) {
992                         memcpy (p, q, _line_size[i]);
993                         p += stride()[i];
994                         /* AVFrame's linesize is what we call `stride' */
995                         q += frame->linesize[i];
996                 }
997         }
998 }
999
1000 Image::Image (shared_ptr<const Image> other, bool aligned)
1001         : _size (other->_size)
1002         , _pixel_format (other->_pixel_format)
1003         , _aligned (aligned)
1004 {
1005         allocate ();
1006
1007         for (int i = 0; i < planes(); ++i) {
1008                 DCPOMATIC_ASSERT (line_size()[i] == other->line_size()[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&
1021 Image::operator= (Image const & other)
1022 {
1023         if (this == &other) {
1024                 return *this;
1025         }
1026
1027         Image tmp (other);
1028         swap (tmp);
1029         return *this;
1030 }
1031
1032 void
1033 Image::swap (Image & other)
1034 {
1035         std::swap (_size, other._size);
1036         std::swap (_pixel_format, other._pixel_format);
1037
1038         for (int i = 0; i < 4; ++i) {
1039                 std::swap (_data[i], other._data[i]);
1040                 std::swap (_line_size[i], other._line_size[i]);
1041                 std::swap (_stride[i], other._stride[i]);
1042         }
1043
1044         std::swap (_aligned, other._aligned);
1045 }
1046
1047 Image::~Image ()
1048 {
1049         for (int i = 0; i < planes(); ++i) {
1050                 av_free (_data[i]);
1051         }
1052
1053         av_free (_data);
1054         av_free (_line_size);
1055         av_free (_stride);
1056 }
1057
1058 uint8_t * const *
1059 Image::data () const
1060 {
1061         return _data;
1062 }
1063
1064 int const *
1065 Image::line_size () const
1066 {
1067         return _line_size;
1068 }
1069
1070 int const *
1071 Image::stride () const
1072 {
1073         return _stride;
1074 }
1075
1076 dcp::Size
1077 Image::size () const
1078 {
1079         return _size;
1080 }
1081
1082 bool
1083 Image::aligned () const
1084 {
1085         return _aligned;
1086 }
1087
1088
1089 PositionImage
1090 merge (list<PositionImage> images)
1091 {
1092         if (images.empty ()) {
1093                 return {};
1094         }
1095
1096         if (images.size() == 1) {
1097                 return images.front ();
1098         }
1099
1100         dcpomatic::Rect<int> all (images.front().position, images.front().image->size().width, images.front().image->size().height);
1101         for (auto const& i: images) {
1102                 all.extend (dcpomatic::Rect<int>(i.position, i.image->size().width, i.image->size().height));
1103         }
1104
1105         auto merged = make_shared<Image>(images.front().image->pixel_format(), dcp::Size(all.width, all.height), true);
1106         merged->make_transparent ();
1107         for (auto const& i: images) {
1108                 merged->alpha_blend (i.image, i.position - all.position());
1109         }
1110
1111         return PositionImage (merged, all.position ());
1112 }
1113
1114
1115 bool
1116 operator== (Image const & a, Image const & b)
1117 {
1118         if (a.planes() != b.planes() || a.pixel_format() != b.pixel_format() || a.aligned() != b.aligned()) {
1119                 return false;
1120         }
1121
1122         for (int c = 0; c < a.planes(); ++c) {
1123                 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]) {
1124                         return false;
1125                 }
1126
1127                 uint8_t* p = a.data()[c];
1128                 uint8_t* q = b.data()[c];
1129                 int const lines = a.sample_size(c).height;
1130                 for (int y = 0; y < lines; ++y) {
1131                         if (memcmp (p, q, a.line_size()[c]) != 0) {
1132                                 return false;
1133                         }
1134
1135                         p += a.stride()[c];
1136                         q += b.stride()[c];
1137                 }
1138         }
1139
1140         return true;
1141 }
1142
1143 /** Fade the image.
1144  *  @param f Amount to fade by; 0 is black, 1 is no fade.
1145  */
1146 void
1147 Image::fade (float f)
1148 {
1149         /* U/V black value for 8-bit colour */
1150         static int const eight_bit_uv =    (1 << 7) - 1;
1151         /* U/V black value for 10-bit colour */
1152         static uint16_t const ten_bit_uv = (1 << 9) - 1;
1153
1154         switch (_pixel_format) {
1155         case AV_PIX_FMT_YUV420P:
1156         {
1157                 /* Y */
1158                 uint8_t* p = data()[0];
1159                 int const lines = sample_size(0).height;
1160                 for (int y = 0; y < lines; ++y) {
1161                         uint8_t* q = p;
1162                         for (int x = 0; x < line_size()[0]; ++x) {
1163                                 *q = int(float(*q) * f);
1164                                 ++q;
1165                         }
1166                         p += stride()[0];
1167                 }
1168
1169                 /* U, V */
1170                 for (int c = 1; c < 3; ++c) {
1171                         uint8_t* p = data()[c];
1172                         int const lines = sample_size(c).height;
1173                         for (int y = 0; y < lines; ++y) {
1174                                 uint8_t* q = p;
1175                                 for (int x = 0; x < line_size()[c]; ++x) {
1176                                         *q = eight_bit_uv + int((int(*q) - eight_bit_uv) * f);
1177                                         ++q;
1178                                 }
1179                                 p += stride()[c];
1180                         }
1181                 }
1182
1183                 break;
1184         }
1185
1186         case AV_PIX_FMT_RGB24:
1187         {
1188                 /* 8-bit */
1189                 uint8_t* p = data()[0];
1190                 int const lines = sample_size(0).height;
1191                 for (int y = 0; y < lines; ++y) {
1192                         uint8_t* q = p;
1193                         for (int x = 0; x < line_size()[0]; ++x) {
1194                                 *q = int (float (*q) * f);
1195                                 ++q;
1196                         }
1197                         p += stride()[0];
1198                 }
1199                 break;
1200         }
1201
1202         case AV_PIX_FMT_XYZ12LE:
1203         case AV_PIX_FMT_RGB48LE:
1204                 /* 16-bit little-endian */
1205                 for (int c = 0; c < 3; ++c) {
1206                         int const stride_pixels = stride()[c] / 2;
1207                         int const line_size_pixels = line_size()[c] / 2;
1208                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1209                         int const lines = sample_size(c).height;
1210                         for (int y = 0; y < lines; ++y) {
1211                                 uint16_t* q = p;
1212                                 for (int x = 0; x < line_size_pixels; ++x) {
1213                                         *q = int (float (*q) * f);
1214                                         ++q;
1215                                 }
1216                                 p += stride_pixels;
1217                         }
1218                 }
1219                 break;
1220
1221         case AV_PIX_FMT_YUV422P10LE:
1222         {
1223                 /* Y */
1224                 {
1225                         int const stride_pixels = stride()[0] / 2;
1226                         int const line_size_pixels = line_size()[0] / 2;
1227                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[0]);
1228                         int const lines = sample_size(0).height;
1229                         for (int y = 0; y < lines; ++y) {
1230                                 uint16_t* q = p;
1231                                 for (int x = 0; x < line_size_pixels; ++x) {
1232                                         *q = int(float(*q) * f);
1233                                         ++q;
1234                                 }
1235                                 p += stride_pixels;
1236                         }
1237                 }
1238
1239                 /* U, V */
1240                 for (int c = 1; c < 3; ++c) {
1241                         int const stride_pixels = stride()[c] / 2;
1242                         int const line_size_pixels = line_size()[c] / 2;
1243                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1244                         int const lines = sample_size(c).height;
1245                         for (int y = 0; y < lines; ++y) {
1246                                 uint16_t* q = p;
1247                                 for (int x = 0; x < line_size_pixels; ++x) {
1248                                         *q = ten_bit_uv + int((int(*q) - ten_bit_uv) * f);
1249                                         ++q;
1250                                 }
1251                                 p += stride_pixels;
1252                         }
1253                 }
1254                 break;
1255
1256         }
1257
1258         default:
1259                 throw PixelFormatError ("fade()", _pixel_format);
1260         }
1261 }
1262
1263 shared_ptr<const Image>
1264 Image::ensure_aligned (shared_ptr<const Image> image)
1265 {
1266         if (image->aligned()) {
1267                 return image;
1268         }
1269
1270         return make_shared<Image>(image, true);
1271 }
1272
1273 size_t
1274 Image::memory_used () const
1275 {
1276         size_t m = 0;
1277         for (int i = 0; i < planes(); ++i) {
1278                 m += _stride[i] * sample_size(i).height;
1279         }
1280         return m;
1281 }
1282
1283 class Memory
1284 {
1285 public:
1286         Memory ()
1287                 : data(0)
1288                 , size(0)
1289         {}
1290
1291         ~Memory ()
1292         {
1293                 free (data);
1294         }
1295
1296         uint8_t* data;
1297         size_t size;
1298 };
1299
1300 static void
1301 png_write_data (png_structp png_ptr, png_bytep data, png_size_t length)
1302 {
1303         auto mem = reinterpret_cast<Memory*>(png_get_io_ptr(png_ptr));
1304         size_t size = mem->size + length;
1305
1306         if (mem->data) {
1307                 mem->data = reinterpret_cast<uint8_t*>(realloc(mem->data, size));
1308         } else {
1309                 mem->data = reinterpret_cast<uint8_t*>(malloc(size));
1310         }
1311
1312         if (!mem->data) {
1313                 throw EncodeError (N_("could not allocate memory for PNG"));
1314         }
1315
1316         memcpy (mem->data + mem->size, data, length);
1317         mem->size += length;
1318 }
1319
1320 static void
1321 png_flush (png_structp)
1322 {
1323
1324 }
1325
1326 static void
1327 png_error_fn (png_structp png_ptr, char const * message)
1328 {
1329         reinterpret_cast<Image*>(png_get_error_ptr(png_ptr))->png_error (message);
1330 }
1331
1332 void
1333 Image::png_error (char const * message)
1334 {
1335         throw EncodeError (String::compose ("Error during PNG write: %1", message));
1336 }
1337
1338 dcp::ArrayData
1339 Image::as_png () const
1340 {
1341         DCPOMATIC_ASSERT (bytes_per_pixel(0) == 4);
1342         DCPOMATIC_ASSERT (planes() == 1);
1343         if (pixel_format() != AV_PIX_FMT_RGBA) {
1344                 return convert_pixel_format(dcp::YUVToRGB::REC709, AV_PIX_FMT_RGBA, true, false)->as_png();
1345         }
1346
1347         /* error handling? */
1348         png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, reinterpret_cast<void*>(const_cast<Image*>(this)), png_error_fn, 0);
1349         if (!png_ptr) {
1350                 throw EncodeError (N_("could not create PNG write struct"));
1351         }
1352
1353         Memory state;
1354
1355         png_set_write_fn (png_ptr, &state, png_write_data, png_flush);
1356
1357         png_infop info_ptr = png_create_info_struct(png_ptr);
1358         if (!info_ptr) {
1359                 png_destroy_write_struct (&png_ptr, &info_ptr);
1360                 throw EncodeError (N_("could not create PNG info struct"));
1361         }
1362
1363         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);
1364
1365         png_byte ** row_pointers = reinterpret_cast<png_byte **>(png_malloc(png_ptr, size().height * sizeof(png_byte *)));
1366         for (int i = 0; i < size().height; ++i) {
1367                 row_pointers[i] = (png_byte *) (data()[0] + i * stride()[0]);
1368         }
1369
1370         png_write_info (png_ptr, info_ptr);
1371         png_write_image (png_ptr, row_pointers);
1372         png_write_end (png_ptr, info_ptr);
1373
1374         png_destroy_write_struct (&png_ptr, &info_ptr);
1375         png_free (png_ptr, row_pointers);
1376
1377         return dcp::ArrayData (state.data, state.size);
1378 }
1379
1380
1381 void
1382 Image::video_range_to_full_range ()
1383 {
1384         switch (_pixel_format) {
1385         case AV_PIX_FMT_RGB24:
1386         {
1387                 float const factor = 256.0 / 219.0;
1388                 uint8_t* p = data()[0];
1389                 int const lines = sample_size(0).height;
1390                 for (int y = 0; y < lines; ++y) {
1391                         uint8_t* q = p;
1392                         for (int x = 0; x < line_size()[0]; ++x) {
1393                                 *q = int((*q - 16) * factor);
1394                                 ++q;
1395                         }
1396                         p += stride()[0];
1397                 }
1398                 break;
1399         }
1400         case AV_PIX_FMT_GBRP12LE:
1401         {
1402                 float const factor = 4096.0 / 3504.0;
1403                 for (int c = 0; c < 3; ++c) {
1404                         uint16_t* p = reinterpret_cast<uint16_t*>(data()[c]);
1405                         int const lines = sample_size(c).height;
1406                         for (int y = 0; y < lines; ++y) {
1407                                 uint16_t* q = p;
1408                                 int const line_size_pixels = line_size()[c] / 2;
1409                                 for (int x = 0; x < line_size_pixels; ++x) {
1410                                         *q = int((*q - 256) * factor);
1411                                         ++q;
1412                                 }
1413                         }
1414                 }
1415                 break;
1416         }
1417         default:
1418                 throw PixelFormatError ("video_range_to_full_range()", _pixel_format);
1419         }
1420 }
1421