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