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