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