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