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