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