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