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