d3b193e7bc99a7d17c5c103489118809a3875d33
[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 && _pixel_format != AV_PIX_FMT_RGBA) {
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 RGBA or BGRA images */
483         DCPOMATIC_ASSERT (other->pixel_format() == AV_PIX_FMT_BGRA || other->pixel_format() == AV_PIX_FMT_RGBA);
484         int const blue = other->pixel_format() == AV_PIX_FMT_BGRA ? 0 : 2;
485         int const red = other->pixel_format() == AV_PIX_FMT_BGRA ? 2 : 0;
486
487         int const other_bpp = 4;
488
489         int start_tx = position.x;
490         int start_ox = 0;
491
492         if (start_tx < 0) {
493                 start_ox = -start_tx;
494                 start_tx = 0;
495         }
496
497         int start_ty = position.y;
498         int start_oy = 0;
499
500         if (start_ty < 0) {
501                 start_oy = -start_ty;
502                 start_ty = 0;
503         }
504
505         switch (_pixel_format) {
506         case AV_PIX_FMT_RGB24:
507         {
508                 /* Going onto RGB24.  First byte is red, second green, third blue */
509                 int const this_bpp = 3;
510                 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
511                         uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
512                         uint8_t* op = other->data()[0] + oy * other->stride()[0];
513                         for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
514                                 float const alpha = float (op[3]) / 255;
515                                 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
516                                 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
517                                 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
518
519                                 tp += this_bpp;
520                                 op += other_bpp;
521                         }
522                 }
523                 break;
524         }
525         case AV_PIX_FMT_BGRA:
526         {
527                 int const this_bpp = 4;
528                 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
529                         uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
530                         uint8_t* op = other->data()[0] + oy * other->stride()[0];
531                         for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
532                                 float const alpha = float (op[3]) / 255;
533                                 tp[0] = op[blue] * alpha + tp[0] * (1 - alpha);
534                                 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
535                                 tp[2] = op[red] * alpha + tp[2] * (1 - alpha);
536                                 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
537
538                                 tp += this_bpp;
539                                 op += other_bpp;
540                         }
541                 }
542                 break;
543         }
544         case AV_PIX_FMT_RGBA:
545         {
546                 int const this_bpp = 4;
547                 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
548                         uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
549                         uint8_t* op = other->data()[0] + oy * other->stride()[0];
550                         for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
551                                 float const alpha = float (op[3]) / 255;
552                                 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
553                                 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
554                                 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
555                                 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
556
557                                 tp += this_bpp;
558                                 op += other_bpp;
559                         }
560                 }
561                 break;
562         }
563         case AV_PIX_FMT_RGB48LE:
564         {
565                 int const this_bpp = 6;
566                 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
567                         uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
568                         uint8_t* op = other->data()[0] + oy * other->stride()[0];
569                         for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
570                                 float const alpha = float (op[3]) / 255;
571                                 /* Blend high bytes */
572                                 tp[1] = op[red] * alpha + tp[1] * (1 - alpha);
573                                 tp[3] = op[1] * alpha + tp[3] * (1 - alpha);
574                                 tp[5] = op[blue] * alpha + tp[5] * (1 - alpha);
575
576                                 tp += this_bpp;
577                                 op += other_bpp;
578                         }
579                 }
580                 break;
581         }
582         case AV_PIX_FMT_XYZ12LE:
583         {
584                 dcp::ColourConversion conv = dcp::ColourConversion::srgb_to_xyz();
585                 double fast_matrix[9];
586                 dcp::combined_rgb_to_xyz (conv, fast_matrix);
587                 double const * lut_in = conv.in()->lut (8, false);
588                 double const * lut_out = conv.out()->lut (16, true);
589                 int const this_bpp = 6;
590                 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
591                         uint16_t* tp = reinterpret_cast<uint16_t*> (data()[0] + ty * stride()[0] + start_tx * this_bpp);
592                         uint8_t* op = other->data()[0] + oy * other->stride()[0];
593                         for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
594                                 float const alpha = float (op[3]) / 255;
595
596                                 /* Convert sRGB to XYZ; op is BGRA.  First, input gamma LUT */
597                                 double const r = lut_in[op[red]];
598                                 double const g = lut_in[op[1]];
599                                 double const b = lut_in[op[blue]];
600
601                                 /* RGB to XYZ, including Bradford transform and DCI companding */
602                                 double const x = max (0.0, min (65535.0, r * fast_matrix[0] + g * fast_matrix[1] + b * fast_matrix[2]));
603                                 double const y = max (0.0, min (65535.0, r * fast_matrix[3] + g * fast_matrix[4] + b * fast_matrix[5]));
604                                 double const z = max (0.0, min (65535.0, r * fast_matrix[6] + g * fast_matrix[7] + b * fast_matrix[8]));
605
606                                 /* Out gamma LUT and blend */
607                                 tp[0] = lrint(lut_out[lrint(x)] * 65535) * alpha + tp[0] * (1 - alpha);
608                                 tp[1] = lrint(lut_out[lrint(y)] * 65535) * alpha + tp[1] * (1 - alpha);
609                                 tp[2] = lrint(lut_out[lrint(z)] * 65535) * alpha + tp[2] * (1 - alpha);
610
611                                 tp += this_bpp / 2;
612                                 op += other_bpp;
613                         }
614                 }
615                 break;
616         }
617         case AV_PIX_FMT_YUV420P:
618         {
619                 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
620                 dcp::Size const ts = size();
621                 dcp::Size const os = yuv->size();
622                 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
623                         int const hty = ty / 2;
624                         int const hoy = oy / 2;
625                         uint8_t* tY = data()[0] + (ty * stride()[0]) + start_tx;
626                         uint8_t* tU = data()[1] + (hty * stride()[1]) + start_tx / 2;
627                         uint8_t* tV = data()[2] + (hty * stride()[2]) + start_tx / 2;
628                         uint8_t* oY = yuv->data()[0] + (oy * yuv->stride()[0]) + start_ox;
629                         uint8_t* oU = yuv->data()[1] + (hoy * yuv->stride()[1]) + start_ox / 2;
630                         uint8_t* oV = yuv->data()[2] + (hoy * yuv->stride()[2]) + start_ox / 2;
631                         uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
632                         for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
633                                 float const a = float(alpha[3]) / 255;
634                                 *tY = *oY * a + *tY * (1 - a);
635                                 *tU = *oU * a + *tU * (1 - a);
636                                 *tV = *oV * a + *tV * (1 - a);
637                                 ++tY;
638                                 ++oY;
639                                 if (tx % 2) {
640                                         ++tU;
641                                         ++tV;
642                                 }
643                                 if (ox % 2) {
644                                         ++oU;
645                                         ++oV;
646                                 }
647                                 alpha += 4;
648                         }
649                 }
650                 break;
651         }
652         case AV_PIX_FMT_YUV420P10:
653         {
654                 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
655                 dcp::Size const ts = size();
656                 dcp::Size const os = yuv->size();
657                 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
658                         int const hty = ty / 2;
659                         int const hoy = oy / 2;
660                         uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
661                         uint16_t* tU = ((uint16_t *) (data()[1] + (hty * stride()[1]))) + start_tx / 2;
662                         uint16_t* tV = ((uint16_t *) (data()[2] + (hty * stride()[2]))) + start_tx / 2;
663                         uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
664                         uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (hoy * yuv->stride()[1]))) + start_ox / 2;
665                         uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (hoy * yuv->stride()[2]))) + start_ox / 2;
666                         uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
667                         for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
668                                 float const a = float(alpha[3]) / 255;
669                                 *tY = *oY * a + *tY * (1 - a);
670                                 *tU = *oU * a + *tU * (1 - a);
671                                 *tV = *oV * a + *tV * (1 - a);
672                                 ++tY;
673                                 ++oY;
674                                 if (tx % 2) {
675                                         ++tU;
676                                         ++tV;
677                                 }
678                                 if (ox % 2) {
679                                         ++oU;
680                                         ++oV;
681                                 }
682                                 alpha += 4;
683                         }
684                 }
685                 break;
686         }
687         case AV_PIX_FMT_YUV422P10LE:
688         {
689                 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
690                 dcp::Size const ts = size();
691                 dcp::Size const os = yuv->size();
692                 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
693                         uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
694                         uint16_t* tU = ((uint16_t *) (data()[1] + (ty * stride()[1]))) + start_tx / 2;
695                         uint16_t* tV = ((uint16_t *) (data()[2] + (ty * stride()[2]))) + start_tx / 2;
696                         uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
697                         uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (oy * yuv->stride()[1]))) + start_ox / 2;
698                         uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (oy * yuv->stride()[2]))) + start_ox / 2;
699                         uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
700                         for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
701                                 float const a = float(alpha[3]) / 255;
702                                 *tY = *oY * a + *tY * (1 - a);
703                                 *tU = *oU * a + *tU * (1 - a);
704                                 *tV = *oV * a + *tV * (1 - a);
705                                 ++tY;
706                                 ++oY;
707                                 if (tx % 2) {
708                                         ++tU;
709                                         ++tV;
710                                 }
711                                 if (ox % 2) {
712                                         ++oU;
713                                         ++oV;
714                                 }
715                                 alpha += 4;
716                         }
717                 }
718                 break;
719         }
720         default:
721                 throw PixelFormatError ("alpha_blend()", _pixel_format);
722         }
723 }
724
725 void
726 Image::copy (shared_ptr<const Image> other, Position<int> position)
727 {
728         /* Only implemented for RGB24 onto RGB24 so far */
729         DCPOMATIC_ASSERT (_pixel_format == AV_PIX_FMT_RGB24 && other->pixel_format() == AV_PIX_FMT_RGB24);
730         DCPOMATIC_ASSERT (position.x >= 0 && position.y >= 0);
731
732         int const N = min (position.x + other->size().width, size().width) - position.x;
733         for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
734                 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
735                 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
736                 memcpy (tp, op, N * 3);
737         }
738 }
739
740 void
741 Image::read_from_socket (shared_ptr<Socket> socket)
742 {
743         for (int i = 0; i < planes(); ++i) {
744                 uint8_t* p = data()[i];
745                 int const lines = sample_size(i).height;
746                 for (int y = 0; y < lines; ++y) {
747                         socket->read (p, line_size()[i]);
748                         p += stride()[i];
749                 }
750         }
751 }
752
753 void
754 Image::write_to_socket (shared_ptr<Socket> socket) const
755 {
756         for (int i = 0; i < planes(); ++i) {
757                 uint8_t* p = data()[i];
758                 int const lines = sample_size(i).height;
759                 for (int y = 0; y < lines; ++y) {
760                         socket->write (p, line_size()[i]);
761                         p += stride()[i];
762                 }
763         }
764 }
765
766 float
767 Image::bytes_per_pixel (int c) const
768 {
769         AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
770         if (!d) {
771                 throw PixelFormatError ("bytes_per_pixel()", _pixel_format);
772         }
773
774         if (c >= planes()) {
775                 return 0;
776         }
777
778         float bpp[4] = { 0, 0, 0, 0 };
779
780 #ifdef DCPOMATIC_HAVE_AVCOMPONENTDESCRIPTOR_DEPTH_MINUS1
781         bpp[0] = floor ((d->comp[0].depth_minus1 + 8) / 8);
782         if (d->nb_components > 1) {
783                 bpp[1] = floor ((d->comp[1].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
784         }
785         if (d->nb_components > 2) {
786                 bpp[2] = floor ((d->comp[2].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
787         }
788         if (d->nb_components > 3) {
789                 bpp[3] = floor ((d->comp[3].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
790         }
791 #else
792         bpp[0] = floor ((d->comp[0].depth + 7) / 8);
793         if (d->nb_components > 1) {
794                 bpp[1] = floor ((d->comp[1].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
795         }
796         if (d->nb_components > 2) {
797                 bpp[2] = floor ((d->comp[2].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
798         }
799         if (d->nb_components > 3) {
800                 bpp[3] = floor ((d->comp[3].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
801         }
802 #endif
803
804         if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
805                 /* Not planar; sum them up */
806                 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
807         }
808
809         return bpp[c];
810 }
811
812 /** Construct a Image of a given size and format, allocating memory
813  *  as required.
814  *
815  *  @param p Pixel format.
816  *  @param s Size in pixels.
817  *  @param aligned true to make each row of this image aligned to a 32-byte boundary.
818  *  @param extra_pixels Amount of extra "run-off" memory to allocate at the end of each plane in pixels.
819  */
820 Image::Image (AVPixelFormat p, dcp::Size s, bool aligned, int extra_pixels)
821         : _size (s)
822         , _pixel_format (p)
823         , _aligned (aligned)
824         , _extra_pixels (extra_pixels)
825 {
826         allocate ();
827 }
828
829 void
830 Image::allocate ()
831 {
832         _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
833         _data[0] = _data[1] = _data[2] = _data[3] = 0;
834
835         _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
836         _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
837
838         _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
839         _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
840
841         for (int i = 0; i < planes(); ++i) {
842                 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
843                 _stride[i] = stride_round_up (i, _line_size, _aligned ? 32 : 1);
844
845                 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
846                    uses a 16-byte fetch to read three bytes (R/G/B) of image data.
847                    Hence on the last pixel of the last line it reads over the end of
848                    the actual data by 1 byte.  If the width of an image is a multiple
849                    of the stride alignment there will be no padding at the end of image lines.
850                    OS X crashes on this illegal read, though other operating systems don't
851                    seem to mind.  The nasty + 1 in this malloc makes sure there is always a byte
852                    for that instruction to read safely.
853
854                    Further to the above, valgrind is now telling me that ff_rgb24ToY_ssse3
855                    over-reads by more then _avx.  I can't follow the code to work out how much,
856                    so I'll just over-allocate by 32 bytes and have done with it.  Empirical
857                    testing suggests that it works.
858                 */
859                 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * sample_size(i).height + _extra_pixels * bytes_per_pixel(i) + 32);
860 #if HAVE_VALGRIND_MEMCHECK_H
861                 /* The data between the end of the line size and the stride is undefined but processed by
862                    libswscale, causing lots of valgrind errors.  Mark it all defined to quell these errors.
863                 */
864                 VALGRIND_MAKE_MEM_DEFINED (_data[i], _stride[i] * sample_size(i).height + _extra_pixels * bytes_per_pixel(i) + 32);
865 #endif
866         }
867 }
868
869 Image::Image (Image const & other)
870         : boost::enable_shared_from_this<Image>(other)
871         , _size (other._size)
872         , _pixel_format (other._pixel_format)
873         , _aligned (other._aligned)
874         , _extra_pixels (other._extra_pixels)
875 {
876         allocate ();
877
878         for (int i = 0; i < planes(); ++i) {
879                 uint8_t* p = _data[i];
880                 uint8_t* q = other._data[i];
881                 int const lines = sample_size(i).height;
882                 for (int j = 0; j < lines; ++j) {
883                         memcpy (p, q, _line_size[i]);
884                         p += stride()[i];
885                         q += other.stride()[i];
886                 }
887         }
888 }
889
890 Image::Image (AVFrame* frame)
891         : _size (frame->width, frame->height)
892         , _pixel_format (static_cast<AVPixelFormat> (frame->format))
893         , _aligned (true)
894         , _extra_pixels (0)
895 {
896         allocate ();
897
898         for (int i = 0; i < planes(); ++i) {
899                 uint8_t* p = _data[i];
900                 uint8_t* q = frame->data[i];
901                 int const lines = sample_size(i).height;
902                 for (int j = 0; j < lines; ++j) {
903                         memcpy (p, q, _line_size[i]);
904                         p += stride()[i];
905                         /* AVFrame's linesize is what we call `stride' */
906                         q += frame->linesize[i];
907                 }
908         }
909 }
910
911 Image::Image (shared_ptr<const Image> other, bool aligned)
912         : _size (other->_size)
913         , _pixel_format (other->_pixel_format)
914         , _aligned (aligned)
915         , _extra_pixels (other->_extra_pixels)
916 {
917         allocate ();
918
919         for (int i = 0; i < planes(); ++i) {
920                 DCPOMATIC_ASSERT (line_size()[i] == other->line_size()[i]);
921                 uint8_t* p = _data[i];
922                 uint8_t* q = other->data()[i];
923                 int const lines = sample_size(i).height;
924                 for (int j = 0; j < lines; ++j) {
925                         memcpy (p, q, line_size()[i]);
926                         p += stride()[i];
927                         q += other->stride()[i];
928                 }
929         }
930 }
931
932 Image&
933 Image::operator= (Image const & other)
934 {
935         if (this == &other) {
936                 return *this;
937         }
938
939         Image tmp (other);
940         swap (tmp);
941         return *this;
942 }
943
944 void
945 Image::swap (Image & other)
946 {
947         std::swap (_size, other._size);
948         std::swap (_pixel_format, other._pixel_format);
949
950         for (int i = 0; i < 4; ++i) {
951                 std::swap (_data[i], other._data[i]);
952                 std::swap (_line_size[i], other._line_size[i]);
953                 std::swap (_stride[i], other._stride[i]);
954         }
955
956         std::swap (_aligned, other._aligned);
957         std::swap (_extra_pixels, other._extra_pixels);
958 }
959
960 /** Destroy a Image */
961 Image::~Image ()
962 {
963         for (int i = 0; i < planes(); ++i) {
964                 av_free (_data[i]);
965         }
966
967         av_free (_data);
968         av_free (_line_size);
969         av_free (_stride);
970 }
971
972 uint8_t * const *
973 Image::data () const
974 {
975         return _data;
976 }
977
978 int const *
979 Image::line_size () const
980 {
981         return _line_size;
982 }
983
984 int const *
985 Image::stride () const
986 {
987         return _stride;
988 }
989
990 dcp::Size
991 Image::size () const
992 {
993         return _size;
994 }
995
996 bool
997 Image::aligned () const
998 {
999         return _aligned;
1000 }
1001
1002 PositionImage
1003 merge (list<PositionImage> images)
1004 {
1005         if (images.empty ()) {
1006                 return PositionImage ();
1007         }
1008
1009         if (images.size() == 1) {
1010                 return images.front ();
1011         }
1012
1013         dcpomatic::Rect<int> all (images.front().position, images.front().image->size().width, images.front().image->size().height);
1014         for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1015                 all.extend (dcpomatic::Rect<int> (i->position, i->image->size().width, i->image->size().height));
1016         }
1017
1018         shared_ptr<Image> merged (new Image (images.front().image->pixel_format (), dcp::Size (all.width, all.height), true));
1019         merged->make_transparent ();
1020         for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1021                 merged->alpha_blend (i->image, i->position - all.position());
1022         }
1023
1024         return PositionImage (merged, all.position ());
1025 }
1026
1027 bool
1028 operator== (Image const & a, Image const & b)
1029 {
1030         if (a.planes() != b.planes() || a.pixel_format() != b.pixel_format() || a.aligned() != b.aligned()) {
1031                 return false;
1032         }
1033
1034         for (int c = 0; c < a.planes(); ++c) {
1035                 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]) {
1036                         return false;
1037                 }
1038
1039                 uint8_t* p = a.data()[c];
1040                 uint8_t* q = b.data()[c];
1041                 int const lines = a.sample_size(c).height;
1042                 for (int y = 0; y < lines; ++y) {
1043                         if (memcmp (p, q, a.line_size()[c]) != 0) {
1044                                 return false;
1045                         }
1046
1047                         p += a.stride()[c];
1048                         q += b.stride()[c];
1049                 }
1050         }
1051
1052         return true;
1053 }
1054
1055 /** Fade the image.
1056  *  @param f Amount to fade by; 0 is black, 1 is no fade.
1057  */
1058 void
1059 Image::fade (float f)
1060 {
1061         /* U/V black value for 8-bit colour */
1062         static int const eight_bit_uv =    (1 << 7) - 1;
1063         /* U/V black value for 10-bit colour */
1064         static uint16_t const ten_bit_uv = (1 << 9) - 1;
1065
1066         switch (_pixel_format) {
1067         case AV_PIX_FMT_YUV420P:
1068         {
1069                 /* Y */
1070                 uint8_t* p = data()[0];
1071                 int const lines = sample_size(0).height;
1072                 for (int y = 0; y < lines; ++y) {
1073                         uint8_t* q = p;
1074                         for (int x = 0; x < line_size()[0]; ++x) {
1075                                 *q = int(float(*q) * f);
1076                                 ++q;
1077                         }
1078                         p += stride()[0];
1079                 }
1080
1081                 /* U, V */
1082                 for (int c = 1; c < 3; ++c) {
1083                         uint8_t* p = data()[c];
1084                         int const lines = sample_size(c).height;
1085                         for (int y = 0; y < lines; ++y) {
1086                                 uint8_t* q = p;
1087                                 for (int x = 0; x < line_size()[c]; ++x) {
1088                                         *q = eight_bit_uv + int((int(*q) - eight_bit_uv) * f);
1089                                         ++q;
1090                                 }
1091                                 p += stride()[c];
1092                         }
1093                 }
1094
1095                 break;
1096         }
1097
1098         case AV_PIX_FMT_RGB24:
1099         {
1100                 /* 8-bit */
1101                 uint8_t* p = data()[0];
1102                 int const lines = sample_size(0).height;
1103                 for (int y = 0; y < lines; ++y) {
1104                         uint8_t* q = p;
1105                         for (int x = 0; x < line_size()[0]; ++x) {
1106                                 *q = int (float (*q) * f);
1107                                 ++q;
1108                         }
1109                         p += stride()[0];
1110                 }
1111                 break;
1112         }
1113
1114         case AV_PIX_FMT_XYZ12LE:
1115         case AV_PIX_FMT_RGB48LE:
1116                 /* 16-bit little-endian */
1117                 for (int c = 0; c < 3; ++c) {
1118                         int const stride_pixels = stride()[c] / 2;
1119                         int const line_size_pixels = line_size()[c] / 2;
1120                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1121                         int const lines = sample_size(c).height;
1122                         for (int y = 0; y < lines; ++y) {
1123                                 uint16_t* q = p;
1124                                 for (int x = 0; x < line_size_pixels; ++x) {
1125                                         *q = int (float (*q) * f);
1126                                         ++q;
1127                                 }
1128                                 p += stride_pixels;
1129                         }
1130                 }
1131                 break;
1132
1133         case AV_PIX_FMT_YUV422P10LE:
1134         {
1135                 /* Y */
1136                 {
1137                         int const stride_pixels = stride()[0] / 2;
1138                         int const line_size_pixels = line_size()[0] / 2;
1139                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[0]);
1140                         int const lines = sample_size(0).height;
1141                         for (int y = 0; y < lines; ++y) {
1142                                 uint16_t* q = p;
1143                                 for (int x = 0; x < line_size_pixels; ++x) {
1144                                         *q = int(float(*q) * f);
1145                                         ++q;
1146                                 }
1147                                 p += stride_pixels;
1148                         }
1149                 }
1150
1151                 /* U, V */
1152                 for (int c = 1; c < 3; ++c) {
1153                         int const stride_pixels = stride()[c] / 2;
1154                         int const line_size_pixels = line_size()[c] / 2;
1155                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1156                         int const lines = sample_size(c).height;
1157                         for (int y = 0; y < lines; ++y) {
1158                                 uint16_t* q = p;
1159                                 for (int x = 0; x < line_size_pixels; ++x) {
1160                                         *q = ten_bit_uv + int((int(*q) - ten_bit_uv) * f);
1161                                         ++q;
1162                                 }
1163                                 p += stride_pixels;
1164                         }
1165                 }
1166                 break;
1167
1168         }
1169
1170         default:
1171                 throw PixelFormatError ("fade()", _pixel_format);
1172         }
1173 }
1174
1175 shared_ptr<const Image>
1176 Image::ensure_aligned (shared_ptr<const Image> image)
1177 {
1178         if (image->aligned()) {
1179                 return image;
1180         }
1181
1182         return shared_ptr<Image> (new Image (image, true));
1183 }
1184
1185 size_t
1186 Image::memory_used () const
1187 {
1188         size_t m = 0;
1189         for (int i = 0; i < planes(); ++i) {
1190                 m += _stride[i] * sample_size(i).height;
1191         }
1192         return m;
1193 }
1194
1195 class Memory
1196 {
1197 public:
1198         Memory ()
1199                 : data(0)
1200                 , size(0)
1201         {}
1202
1203         ~Memory ()
1204         {
1205                 free (data);
1206         }
1207
1208         uint8_t* data;
1209         size_t size;
1210 };
1211
1212 static void
1213 png_write_data (png_structp png_ptr, png_bytep data, png_size_t length)
1214 {
1215         Memory* mem = reinterpret_cast<Memory*>(png_get_io_ptr(png_ptr));
1216         size_t size = mem->size + length;
1217
1218         if (mem->data) {
1219                 mem->data = reinterpret_cast<uint8_t*>(realloc(mem->data, size));
1220         } else {
1221                 mem->data = reinterpret_cast<uint8_t*>(malloc(size));
1222         }
1223
1224         if (!mem->data) {
1225                 throw EncodeError (N_("could not allocate memory for PNG"));
1226         }
1227
1228         memcpy (mem->data + mem->size, data, length);
1229         mem->size += length;
1230 }
1231
1232 static void
1233 png_flush (png_structp)
1234 {
1235
1236 }
1237
1238 static void
1239 png_error_fn (png_structp png_ptr, char const * message)
1240 {
1241         reinterpret_cast<Image*>(png_get_error_ptr(png_ptr))->png_error (message);
1242 }
1243
1244 void
1245 Image::png_error (char const * message)
1246 {
1247         throw EncodeError (String::compose ("Error during PNG write: %1", message));
1248 }
1249
1250 dcp::Data
1251 Image::as_png () const
1252 {
1253         DCPOMATIC_ASSERT (bytes_per_pixel(0) == 4);
1254         DCPOMATIC_ASSERT (planes() == 1);
1255         if (pixel_format() != AV_PIX_FMT_RGBA) {
1256                 return convert_pixel_format(dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_RGBA, true, false)->as_png();
1257         }
1258
1259         /* error handling? */
1260         png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, reinterpret_cast<void*>(const_cast<Image*>(this)), png_error_fn, 0);
1261         if (!png_ptr) {
1262                 throw EncodeError (N_("could not create PNG write struct"));
1263         }
1264
1265         Memory state;
1266
1267         png_set_write_fn (png_ptr, &state, png_write_data, png_flush);
1268
1269         png_infop info_ptr = png_create_info_struct(png_ptr);
1270         if (!info_ptr) {
1271                 png_destroy_write_struct (&png_ptr, &info_ptr);
1272                 throw EncodeError (N_("could not create PNG info struct"));
1273         }
1274
1275         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);
1276
1277         png_byte ** row_pointers = reinterpret_cast<png_byte **>(png_malloc(png_ptr, size().height * sizeof(png_byte *)));
1278         for (int i = 0; i < size().height; ++i) {
1279                 row_pointers[i] = (png_byte *) (data()[0] + i * stride()[0]);
1280         }
1281
1282         png_write_info (png_ptr, info_ptr);
1283         png_write_image (png_ptr, row_pointers);
1284         png_write_end (png_ptr, info_ptr);
1285
1286         png_destroy_write_struct (&png_ptr, &info_ptr);
1287         png_free (png_ptr, row_pointers);
1288
1289         return dcp::Data (state.data, state.size);
1290 }