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