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