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