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