std::shared_ptr
[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 std::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 video_range Video range of the image.
148  *  @param out_format Output pixel format.
149  *  @param out_aligned true to make the output image aligned.
150  *  @param out_video_range Video range to use for the output image.
151  *  @param fast Try to be fast at the possible expense of quality; at present this means using
152  *  fast bilinear rather than bicubic scaling.
153  */
154 shared_ptr<Image>
155 Image::crop_scale_window (
156         Crop crop,
157         dcp::Size inter_size,
158         dcp::Size out_size,
159         dcp::YUVToRGB yuv_to_rgb,
160         VideoRange video_range,
161         AVPixelFormat out_format,
162         VideoRange out_video_range,
163         bool out_aligned,
164         bool fast
165         ) const
166 {
167         /* Empirical testing suggests that sws_scale() will crash if
168            the input image is not aligned.
169         */
170         DCPOMATIC_ASSERT (aligned ());
171
172         DCPOMATIC_ASSERT (out_size.width >= inter_size.width);
173         DCPOMATIC_ASSERT (out_size.height >= inter_size.height);
174
175         shared_ptr<Image> out (new Image(out_format, out_size, out_aligned));
176         out->make_black ();
177
178         AVPixFmtDescriptor const * in_desc = av_pix_fmt_desc_get (_pixel_format);
179         if (!in_desc) {
180                 throw PixelFormatError ("crop_scale_window()", _pixel_format);
181         }
182
183         /* Round down so that we crop only the number of pixels that is straightforward
184          * considering any subsampling.
185          */
186         Crop corrected_crop(
187                 round_width_for_subsampling(crop.left, in_desc),
188                 round_width_for_subsampling(crop.right, in_desc),
189                 round_height_for_subsampling(crop.top, in_desc),
190                 round_height_for_subsampling(crop.bottom, in_desc)
191                 );
192
193         /* Also check that we aren't cropping more image than there actually is */
194         if ((corrected_crop.left + corrected_crop.right) >= (size().width - 4)) {
195                 corrected_crop.left = 0;
196                 corrected_crop.right = size().width - 4;
197         }
198
199         if ((corrected_crop.top + corrected_crop.bottom) >= (size().height - 4)) {
200                 corrected_crop.top = 0;
201                 corrected_crop.bottom = size().height - 4;
202         }
203
204         /* Size of the image after any crop */
205         dcp::Size const cropped_size = corrected_crop.apply (size());
206
207         /* Scale context for a scale from cropped_size to inter_size */
208         struct SwsContext* scale_context = sws_getContext (
209                         cropped_size.width, cropped_size.height, pixel_format(),
210                         inter_size.width, inter_size.height, out_format,
211                         fast ? SWS_FAST_BILINEAR : SWS_BICUBIC, 0, 0, 0
212                 );
213
214         if (!scale_context) {
215                 throw runtime_error (N_("Could not allocate SwsContext"));
216         }
217
218         DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
219         int const lut[dcp::YUV_TO_RGB_COUNT] = {
220                 SWS_CS_ITU601,
221                 SWS_CS_ITU709
222         };
223
224         /* The 3rd parameter here is:
225            0 -> source range MPEG (i.e. "video", 16-235)
226            1 -> source range JPEG (i.e. "full", 0-255)
227            And the 5th:
228            0 -> destination range MPEG (i.e. "video", 16-235)
229            1 -> destination range JPEG (i.e. "full", 0-255)
230
231            But remember: sws_setColorspaceDetails ignores these
232            parameters unless the both source and destination images
233            are isYUV or isGray.  (If either is not, it uses video range).
234         */
235         sws_setColorspaceDetails (
236                 scale_context,
237                 sws_getCoefficients (lut[yuv_to_rgb]), video_range == VIDEO_RANGE_VIDEO ? 0 : 1,
238                 sws_getCoefficients (lut[yuv_to_rgb]), out_video_range == VIDEO_RANGE_VIDEO ? 0 : 1,
239                 0, 1 << 16, 1 << 16
240                 );
241
242         /* Prepare input data pointers with crop */
243         uint8_t* scale_in_data[planes()];
244         for (int c = 0; c < planes(); ++c) {
245                 int const x = lrintf(bytes_per_pixel(c) * corrected_crop.left);
246                 scale_in_data[c] = data()[c] + x + stride()[c] * (corrected_crop.top / vertical_factor(c));
247         }
248
249         AVPixFmtDescriptor const * out_desc = av_pix_fmt_desc_get (out_format);
250         if (!out_desc) {
251                 throw PixelFormatError ("crop_scale_window()", out_format);
252         }
253
254         /* Corner of the image within out_size */
255         Position<int> const corner (
256                 round_width_for_subsampling((out_size.width - inter_size.width) / 2, out_desc),
257                 round_height_for_subsampling((out_size.height - inter_size.height) / 2, out_desc)
258                 );
259
260         uint8_t* scale_out_data[out->planes()];
261         for (int c = 0; c < out->planes(); ++c) {
262                 int const x = lrintf(out->bytes_per_pixel(c) * corner.x);
263                 scale_out_data[c] = out->data()[c] + x + out->stride()[c] * (corner.y / out->vertical_factor(c));
264         }
265
266         sws_scale (
267                 scale_context,
268                 scale_in_data, stride(),
269                 0, cropped_size.height,
270                 scale_out_data, out->stride()
271                 );
272
273         sws_freeContext (scale_context);
274
275         if (corrected_crop != Crop() && cropped_size == inter_size) {
276                 /* We are cropping without any scaling or pixel format conversion, so FFmpeg may have left some
277                    data behind in our image.  Clear it out.  It may get to the point where we should just stop
278                    trying to be clever with cropping.
279                 */
280                 out->make_part_black (corner.x + cropped_size.width, out_size.width - cropped_size.width);
281         }
282
283         return out;
284 }
285
286 shared_ptr<Image>
287 Image::convert_pixel_format (dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
288 {
289         return scale(size(), yuv_to_rgb, out_format, out_aligned, fast);
290 }
291
292 /** @param out_size Size to scale to.
293  *  @param yuv_to_rgb YUVToRGB transform transform to use, if required.
294  *  @param out_format Output pixel format.
295  *  @param out_aligned true to make an aligned output image.
296  *  @param fast Try to be fast at the possible expense of quality; at present this means using
297  *  fast bilinear rather than bicubic scaling.
298  */
299 shared_ptr<Image>
300 Image::scale (dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
301 {
302         /* Empirical testing suggests that sws_scale() will crash if
303            the input image is not aligned.
304         */
305         DCPOMATIC_ASSERT (aligned ());
306
307         shared_ptr<Image> scaled (new Image (out_format, out_size, out_aligned));
308
309         struct SwsContext* scale_context = sws_getContext (
310                 size().width, size().height, pixel_format(),
311                 out_size.width, out_size.height, out_format,
312                 (fast ? SWS_FAST_BILINEAR : SWS_BICUBIC) | SWS_ACCURATE_RND, 0, 0, 0
313                 );
314
315         DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
316         int const lut[dcp::YUV_TO_RGB_COUNT] = {
317                 SWS_CS_ITU601,
318                 SWS_CS_ITU709
319         };
320
321         /* The 3rd parameter here is:
322            0 -> source range MPEG (i.e. "video", 16-235)
323            1 -> source range JPEG (i.e. "full", 0-255)
324            And the 5th:
325            0 -> destination range MPEG (i.e. "video", 16-235)
326            1 -> destination range JPEG (i.e. "full", 0-255)
327
328            But remember: sws_setColorspaceDetails ignores these
329            parameters unless the corresponding image isYUV or isGray.
330            (If it's neither, it uses video range).
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         : std::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 Image::~Image ()
1042 {
1043         for (int i = 0; i < planes(); ++i) {
1044                 av_free (_data[i]);
1045         }
1046
1047         av_free (_data);
1048         av_free (_line_size);
1049         av_free (_stride);
1050 }
1051
1052 uint8_t * const *
1053 Image::data () const
1054 {
1055         return _data;
1056 }
1057
1058 int const *
1059 Image::line_size () const
1060 {
1061         return _line_size;
1062 }
1063
1064 int const *
1065 Image::stride () const
1066 {
1067         return _stride;
1068 }
1069
1070 dcp::Size
1071 Image::size () const
1072 {
1073         return _size;
1074 }
1075
1076 bool
1077 Image::aligned () const
1078 {
1079         return _aligned;
1080 }
1081
1082 PositionImage
1083 merge (list<PositionImage> images)
1084 {
1085         if (images.empty ()) {
1086                 return PositionImage ();
1087         }
1088
1089         if (images.size() == 1) {
1090                 return images.front ();
1091         }
1092
1093         dcpomatic::Rect<int> all (images.front().position, images.front().image->size().width, images.front().image->size().height);
1094         for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1095                 all.extend (dcpomatic::Rect<int> (i->position, i->image->size().width, i->image->size().height));
1096         }
1097
1098         shared_ptr<Image> merged (new Image (images.front().image->pixel_format (), dcp::Size (all.width, all.height), true));
1099         merged->make_transparent ();
1100         for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1101                 merged->alpha_blend (i->image, i->position - all.position());
1102         }
1103
1104         return PositionImage (merged, all.position ());
1105 }
1106
1107 bool
1108 operator== (Image const & a, Image const & b)
1109 {
1110         if (a.planes() != b.planes() || a.pixel_format() != b.pixel_format() || a.aligned() != b.aligned()) {
1111                 return false;
1112         }
1113
1114         for (int c = 0; c < a.planes(); ++c) {
1115                 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]) {
1116                         return false;
1117                 }
1118
1119                 uint8_t* p = a.data()[c];
1120                 uint8_t* q = b.data()[c];
1121                 int const lines = a.sample_size(c).height;
1122                 for (int y = 0; y < lines; ++y) {
1123                         if (memcmp (p, q, a.line_size()[c]) != 0) {
1124                                 return false;
1125                         }
1126
1127                         p += a.stride()[c];
1128                         q += b.stride()[c];
1129                 }
1130         }
1131
1132         return true;
1133 }
1134
1135 /** Fade the image.
1136  *  @param f Amount to fade by; 0 is black, 1 is no fade.
1137  */
1138 void
1139 Image::fade (float f)
1140 {
1141         /* U/V black value for 8-bit colour */
1142         static int const eight_bit_uv =    (1 << 7) - 1;
1143         /* U/V black value for 10-bit colour */
1144         static uint16_t const ten_bit_uv = (1 << 9) - 1;
1145
1146         switch (_pixel_format) {
1147         case AV_PIX_FMT_YUV420P:
1148         {
1149                 /* Y */
1150                 uint8_t* p = data()[0];
1151                 int const lines = sample_size(0).height;
1152                 for (int y = 0; y < lines; ++y) {
1153                         uint8_t* q = p;
1154                         for (int x = 0; x < line_size()[0]; ++x) {
1155                                 *q = int(float(*q) * f);
1156                                 ++q;
1157                         }
1158                         p += stride()[0];
1159                 }
1160
1161                 /* U, V */
1162                 for (int c = 1; c < 3; ++c) {
1163                         uint8_t* p = data()[c];
1164                         int const lines = sample_size(c).height;
1165                         for (int y = 0; y < lines; ++y) {
1166                                 uint8_t* q = p;
1167                                 for (int x = 0; x < line_size()[c]; ++x) {
1168                                         *q = eight_bit_uv + int((int(*q) - eight_bit_uv) * f);
1169                                         ++q;
1170                                 }
1171                                 p += stride()[c];
1172                         }
1173                 }
1174
1175                 break;
1176         }
1177
1178         case AV_PIX_FMT_RGB24:
1179         {
1180                 /* 8-bit */
1181                 uint8_t* p = data()[0];
1182                 int const lines = sample_size(0).height;
1183                 for (int y = 0; y < lines; ++y) {
1184                         uint8_t* q = p;
1185                         for (int x = 0; x < line_size()[0]; ++x) {
1186                                 *q = int (float (*q) * f);
1187                                 ++q;
1188                         }
1189                         p += stride()[0];
1190                 }
1191                 break;
1192         }
1193
1194         case AV_PIX_FMT_XYZ12LE:
1195         case AV_PIX_FMT_RGB48LE:
1196                 /* 16-bit little-endian */
1197                 for (int c = 0; c < 3; ++c) {
1198                         int const stride_pixels = stride()[c] / 2;
1199                         int const line_size_pixels = line_size()[c] / 2;
1200                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1201                         int const lines = sample_size(c).height;
1202                         for (int y = 0; y < lines; ++y) {
1203                                 uint16_t* q = p;
1204                                 for (int x = 0; x < line_size_pixels; ++x) {
1205                                         *q = int (float (*q) * f);
1206                                         ++q;
1207                                 }
1208                                 p += stride_pixels;
1209                         }
1210                 }
1211                 break;
1212
1213         case AV_PIX_FMT_YUV422P10LE:
1214         {
1215                 /* Y */
1216                 {
1217                         int const stride_pixels = stride()[0] / 2;
1218                         int const line_size_pixels = line_size()[0] / 2;
1219                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[0]);
1220                         int const lines = sample_size(0).height;
1221                         for (int y = 0; y < lines; ++y) {
1222                                 uint16_t* q = p;
1223                                 for (int x = 0; x < line_size_pixels; ++x) {
1224                                         *q = int(float(*q) * f);
1225                                         ++q;
1226                                 }
1227                                 p += stride_pixels;
1228                         }
1229                 }
1230
1231                 /* U, V */
1232                 for (int c = 1; c < 3; ++c) {
1233                         int const stride_pixels = stride()[c] / 2;
1234                         int const line_size_pixels = line_size()[c] / 2;
1235                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1236                         int const lines = sample_size(c).height;
1237                         for (int y = 0; y < lines; ++y) {
1238                                 uint16_t* q = p;
1239                                 for (int x = 0; x < line_size_pixels; ++x) {
1240                                         *q = ten_bit_uv + int((int(*q) - ten_bit_uv) * f);
1241                                         ++q;
1242                                 }
1243                                 p += stride_pixels;
1244                         }
1245                 }
1246                 break;
1247
1248         }
1249
1250         default:
1251                 throw PixelFormatError ("fade()", _pixel_format);
1252         }
1253 }
1254
1255 shared_ptr<const Image>
1256 Image::ensure_aligned (shared_ptr<const Image> image)
1257 {
1258         if (image->aligned()) {
1259                 return image;
1260         }
1261
1262         return shared_ptr<Image> (new Image (image, true));
1263 }
1264
1265 size_t
1266 Image::memory_used () const
1267 {
1268         size_t m = 0;
1269         for (int i = 0; i < planes(); ++i) {
1270                 m += _stride[i] * sample_size(i).height;
1271         }
1272         return m;
1273 }
1274
1275 class Memory
1276 {
1277 public:
1278         Memory ()
1279                 : data(0)
1280                 , size(0)
1281         {}
1282
1283         ~Memory ()
1284         {
1285                 free (data);
1286         }
1287
1288         uint8_t* data;
1289         size_t size;
1290 };
1291
1292 static void
1293 png_write_data (png_structp png_ptr, png_bytep data, png_size_t length)
1294 {
1295         Memory* mem = reinterpret_cast<Memory*>(png_get_io_ptr(png_ptr));
1296         size_t size = mem->size + length;
1297
1298         if (mem->data) {
1299                 mem->data = reinterpret_cast<uint8_t*>(realloc(mem->data, size));
1300         } else {
1301                 mem->data = reinterpret_cast<uint8_t*>(malloc(size));
1302         }
1303
1304         if (!mem->data) {
1305                 throw EncodeError (N_("could not allocate memory for PNG"));
1306         }
1307
1308         memcpy (mem->data + mem->size, data, length);
1309         mem->size += length;
1310 }
1311
1312 static void
1313 png_flush (png_structp)
1314 {
1315
1316 }
1317
1318 static void
1319 png_error_fn (png_structp png_ptr, char const * message)
1320 {
1321         reinterpret_cast<Image*>(png_get_error_ptr(png_ptr))->png_error (message);
1322 }
1323
1324 void
1325 Image::png_error (char const * message)
1326 {
1327         throw EncodeError (String::compose ("Error during PNG write: %1", message));
1328 }
1329
1330 dcp::ArrayData
1331 Image::as_png () const
1332 {
1333         DCPOMATIC_ASSERT (bytes_per_pixel(0) == 4);
1334         DCPOMATIC_ASSERT (planes() == 1);
1335         if (pixel_format() != AV_PIX_FMT_RGBA) {
1336                 return convert_pixel_format(dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_RGBA, true, false)->as_png();
1337         }
1338
1339         /* error handling? */
1340         png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, reinterpret_cast<void*>(const_cast<Image*>(this)), png_error_fn, 0);
1341         if (!png_ptr) {
1342                 throw EncodeError (N_("could not create PNG write struct"));
1343         }
1344
1345         Memory state;
1346
1347         png_set_write_fn (png_ptr, &state, png_write_data, png_flush);
1348
1349         png_infop info_ptr = png_create_info_struct(png_ptr);
1350         if (!info_ptr) {
1351                 png_destroy_write_struct (&png_ptr, &info_ptr);
1352                 throw EncodeError (N_("could not create PNG info struct"));
1353         }
1354
1355         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);
1356
1357         png_byte ** row_pointers = reinterpret_cast<png_byte **>(png_malloc(png_ptr, size().height * sizeof(png_byte *)));
1358         for (int i = 0; i < size().height; ++i) {
1359                 row_pointers[i] = (png_byte *) (data()[0] + i * stride()[0]);
1360         }
1361
1362         png_write_info (png_ptr, info_ptr);
1363         png_write_image (png_ptr, row_pointers);
1364         png_write_end (png_ptr, info_ptr);
1365
1366         png_destroy_write_struct (&png_ptr, &info_ptr);
1367         png_free (png_ptr, row_pointers);
1368
1369         return dcp::ArrayData (state.data, state.size);
1370 }
1371
1372
1373 void
1374 Image::video_range_to_full_range ()
1375 {
1376         switch (_pixel_format) {
1377         case AV_PIX_FMT_RGB24:
1378         {
1379                 float const factor = 256.0 / 219.0;
1380                 uint8_t* p = data()[0];
1381                 int const lines = sample_size(0).height;
1382                 for (int y = 0; y < lines; ++y) {
1383                         uint8_t* q = p;
1384                         for (int x = 0; x < line_size()[0]; ++x) {
1385                                 *q = int((*q - 16) * factor);
1386                                 ++q;
1387                         }
1388                         p += stride()[0];
1389                 }
1390                 break;
1391         }
1392         case AV_PIX_FMT_GBRP12LE:
1393         {
1394                 float const factor = 4096.0 / 3504.0;
1395                 for (int c = 0; c < 3; ++c) {
1396                         uint16_t* p = reinterpret_cast<uint16_t*>(data()[c]);
1397                         int const lines = sample_size(c).height;
1398                         for (int y = 0; y < lines; ++y) {
1399                                 uint16_t* q = p;
1400                                 int const line_size_pixels = line_size()[c] / 2;
1401                                 for (int x = 0; x < line_size_pixels; ++x) {
1402                                         *q = int((*q - 256) * factor);
1403                                         ++q;
1404                                 }
1405                         }
1406                 }
1407                 break;
1408         }
1409         default:
1410                 throw PixelFormatError ("video_range_to_full_range()", _pixel_format);
1411         }
1412 }
1413