Remove Scaler config and use SWS_BICUBIC everywhere.
[dcpomatic.git] / src / lib / image.cc
1 /*
2     Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 /** @file src/image.cc
21  *  @brief A class to describe a video image.
22  */
23
24 #include "image.h"
25 #include "exceptions.h"
26 #include "timer.h"
27 #include "rect.h"
28 #include "util.h"
29 #include "md5_digester.h"
30 #include "dcpomatic_socket.h"
31 extern "C" {
32 #include <libswscale/swscale.h>
33 #include <libavutil/pixfmt.h>
34 #include <libavutil/pixdesc.h>
35 }
36 #include <iostream>
37
38 #include "i18n.h"
39
40 using std::string;
41 using std::min;
42 using std::cout;
43 using std::cerr;
44 using std::list;
45 using boost::shared_ptr;
46 using dcp::Size;
47
48 int
49 Image::line_factor (int n) const
50 {
51         if (n == 0) {
52                 return 1;
53         }
54
55         AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
56         if (!d) {
57                 throw PixelFormatError ("lines()", _pixel_format);
58         }
59         
60         return pow (2.0f, d->log2_chroma_h);
61 }
62
63 /** @param n Component index.
64  *  @return Number of lines in the image for the given component.
65  */
66 int
67 Image::lines (int n) const
68 {
69         return rint (ceil (static_cast<double>(size().height) / line_factor (n)));
70 }
71
72 /** @return Number of components */
73 int
74 Image::components () const
75 {
76         AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
77         if (!d) {
78                 throw PixelFormatError ("components()", _pixel_format);
79         }
80
81         if ((d->flags & PIX_FMT_PLANAR) == 0) {
82                 return 1;
83         }
84         
85         return d->nb_components;
86 }
87
88 /** Crop this image, scale it to `inter_size' and then place it in a black frame of `out_size' */
89 shared_ptr<Image>
90 Image::crop_scale_window (Crop crop, dcp::Size inter_size, dcp::Size out_size, AVPixelFormat out_format, bool out_aligned) const
91 {
92         /* Empirical testing suggests that sws_scale() will crash if
93            the input image is not aligned.
94         */
95         DCPOMATIC_ASSERT (aligned ());
96
97         DCPOMATIC_ASSERT (out_size.width >= inter_size.width);
98         DCPOMATIC_ASSERT (out_size.height >= inter_size.height);
99
100         /* Here's an image of out_size */
101         shared_ptr<Image> out (new Image (out_format, out_size, out_aligned));
102         out->make_black ();
103
104         /* Size of the image after any crop */
105         dcp::Size const cropped_size = crop.apply (size ());
106
107         /* Scale context for a scale from cropped_size to inter_size */
108         struct SwsContext* scale_context = sws_getContext (
109                         cropped_size.width, cropped_size.height, pixel_format(),
110                         inter_size.width, inter_size.height, out_format,
111                         SWS_BICUBIC, 0, 0, 0
112                 );
113
114         if (!scale_context) {
115                 throw StringError (N_("Could not allocate SwsContext"));
116         }
117
118         /* Prepare input data pointers with crop */
119         uint8_t* scale_in_data[components()];
120         for (int c = 0; c < components(); ++c) {
121                 scale_in_data[c] = data()[c] + int (rint (bytes_per_pixel(c) * crop.left)) + stride()[c] * (crop.top / line_factor(c));
122         }
123
124         /* Corner of the image within out_size */
125         Position<int> const corner ((out_size.width - inter_size.width) / 2, (out_size.height - inter_size.height) / 2);
126
127         uint8_t* scale_out_data[out->components()];
128         for (int c = 0; c < out->components(); ++c) {
129                 scale_out_data[c] = out->data()[c] + int (rint (out->bytes_per_pixel(c) * corner.x)) + out->stride()[c] * corner.y;
130         }
131
132         sws_scale (
133                 scale_context,
134                 scale_in_data, stride(),
135                 0, cropped_size.height,
136                 scale_out_data, out->stride()
137                 );
138
139         sws_freeContext (scale_context);
140
141         return out;     
142 }
143
144 shared_ptr<Image>
145 Image::scale (dcp::Size out_size, AVPixelFormat out_format, bool out_aligned) const
146 {
147         /* Empirical testing suggests that sws_scale() will crash if
148            the input image is not aligned.
149         */
150         DCPOMATIC_ASSERT (aligned ());
151
152         shared_ptr<Image> scaled (new Image (out_format, out_size, out_aligned));
153
154         struct SwsContext* scale_context = sws_getContext (
155                 size().width, size().height, pixel_format(),
156                 out_size.width, out_size.height, out_format,
157                 SWS_BICUBIC, 0, 0, 0
158                 );
159
160         sws_scale (
161                 scale_context,
162                 data(), stride(),
163                 0, size().height,
164                 scaled->data(), scaled->stride()
165                 );
166
167         sws_freeContext (scale_context);
168
169         return scaled;
170 }
171
172 shared_ptr<Image>
173 Image::crop (Crop crop, bool aligned) const
174 {
175         dcp::Size cropped_size = crop.apply (size ());
176         shared_ptr<Image> out (new Image (pixel_format(), cropped_size, aligned));
177
178         for (int c = 0; c < components(); ++c) {
179                 int const crop_left_in_bytes = bytes_per_pixel(c) * crop.left;
180                 /* bytes_per_pixel() could be a fraction; in this case the stride will be rounded
181                    up, and we need to make sure that we copy over the width (up to the stride)
182                    rather than short of the width; hence the ceil() here.
183                 */
184                 int const cropped_width_in_bytes = ceil (bytes_per_pixel(c) * cropped_size.width);
185
186                 /* Start of the source line, cropped from the top but not the left */
187                 uint8_t* in_p = data()[c] + (crop.top / out->line_factor(c)) * stride()[c];
188                 uint8_t* out_p = out->data()[c];
189
190                 for (int y = 0; y < out->lines(c); ++y) {
191                         memcpy (out_p, in_p + crop_left_in_bytes, cropped_width_in_bytes);
192                         in_p += stride()[c];
193                         out_p += out->stride()[c];
194                 }
195         }
196
197         return out;
198 }
199
200 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
201 void
202 Image::yuv_16_black (uint16_t v, bool alpha)
203 {
204         memset (data()[0], 0, lines(0) * stride()[0]);
205         for (int i = 1; i < 3; ++i) {
206                 int16_t* p = reinterpret_cast<int16_t*> (data()[i]);
207                 for (int y = 0; y < lines(i); ++y) {
208                         /* We divide by 2 here because we are writing 2 bytes at a time */
209                         for (int x = 0; x < line_size()[i] / 2; ++x) {
210                                 p[x] = v;
211                         }
212                         p += stride()[i] / 2;
213                 }
214         }
215
216         if (alpha) {
217                 memset (data()[3], 0, lines(3) * stride()[3]);
218         }
219 }
220
221 uint16_t
222 Image::swap_16 (uint16_t v)
223 {
224         return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
225 }
226
227 void
228 Image::make_black ()
229 {
230         /* U/V black value for 8-bit colour */
231         static uint8_t const eight_bit_uv =     (1 << 7) - 1;
232         /* U/V black value for 9-bit colour */
233         static uint16_t const nine_bit_uv =     (1 << 8) - 1;
234         /* U/V black value for 10-bit colour */
235         static uint16_t const ten_bit_uv =      (1 << 9) - 1;
236         /* U/V black value for 16-bit colour */
237         static uint16_t const sixteen_bit_uv =  (1 << 15) - 1;
238         
239         switch (_pixel_format) {
240         case PIX_FMT_YUV420P:
241         case PIX_FMT_YUV422P:
242         case PIX_FMT_YUV444P:
243         case PIX_FMT_YUV411P:
244                 memset (data()[0], 0, lines(0) * stride()[0]);
245                 memset (data()[1], eight_bit_uv, lines(1) * stride()[1]);
246                 memset (data()[2], eight_bit_uv, lines(2) * stride()[2]);
247                 break;
248
249         case PIX_FMT_YUVJ420P:
250         case PIX_FMT_YUVJ422P:
251         case PIX_FMT_YUVJ444P:
252                 memset (data()[0], 0, lines(0) * stride()[0]);
253                 memset (data()[1], eight_bit_uv + 1, lines(1) * stride()[1]);
254                 memset (data()[2], eight_bit_uv + 1, lines(2) * stride()[2]);
255                 break;
256
257         case PIX_FMT_YUV422P9LE:
258         case PIX_FMT_YUV444P9LE:
259                 yuv_16_black (nine_bit_uv, false);
260                 break;
261
262         case PIX_FMT_YUV422P9BE:
263         case PIX_FMT_YUV444P9BE:
264                 yuv_16_black (swap_16 (nine_bit_uv), false);
265                 break;
266                 
267         case PIX_FMT_YUV422P10LE:
268         case PIX_FMT_YUV444P10LE:
269                 yuv_16_black (ten_bit_uv, false);
270                 break;
271
272         case PIX_FMT_YUV422P16LE:
273         case PIX_FMT_YUV444P16LE:
274                 yuv_16_black (sixteen_bit_uv, false);
275                 break;
276                 
277         case PIX_FMT_YUV444P10BE:
278         case PIX_FMT_YUV422P10BE:
279                 yuv_16_black (swap_16 (ten_bit_uv), false);
280                 break;
281
282         case AV_PIX_FMT_YUVA420P9BE:
283         case AV_PIX_FMT_YUVA422P9BE:
284         case AV_PIX_FMT_YUVA444P9BE:
285                 yuv_16_black (swap_16 (nine_bit_uv), true);
286                 break;
287                 
288         case AV_PIX_FMT_YUVA420P9LE:
289         case AV_PIX_FMT_YUVA422P9LE:
290         case AV_PIX_FMT_YUVA444P9LE:
291                 yuv_16_black (nine_bit_uv, true);
292                 break;
293                 
294         case AV_PIX_FMT_YUVA420P10BE:
295         case AV_PIX_FMT_YUVA422P10BE:
296         case AV_PIX_FMT_YUVA444P10BE:
297                 yuv_16_black (swap_16 (ten_bit_uv), true);
298                 break;
299                 
300         case AV_PIX_FMT_YUVA420P10LE:
301         case AV_PIX_FMT_YUVA422P10LE:
302         case AV_PIX_FMT_YUVA444P10LE:
303                 yuv_16_black (ten_bit_uv, true);
304                 break;
305                 
306         case AV_PIX_FMT_YUVA420P16BE:
307         case AV_PIX_FMT_YUVA422P16BE:
308         case AV_PIX_FMT_YUVA444P16BE:
309                 yuv_16_black (swap_16 (sixteen_bit_uv), true);
310                 break;
311                 
312         case AV_PIX_FMT_YUVA420P16LE:
313         case AV_PIX_FMT_YUVA422P16LE:
314         case AV_PIX_FMT_YUVA444P16LE:
315                 yuv_16_black (sixteen_bit_uv, true);
316                 break;
317
318         case PIX_FMT_RGB24:
319         case PIX_FMT_ARGB:
320         case PIX_FMT_RGBA:
321         case PIX_FMT_ABGR:
322         case PIX_FMT_BGRA:
323         case PIX_FMT_RGB555LE:
324         case PIX_FMT_RGB48LE:
325         case PIX_FMT_RGB48BE:
326                 memset (data()[0], 0, lines(0) * stride()[0]);
327                 break;
328
329         case PIX_FMT_UYVY422:
330         {
331                 int const Y = lines(0);
332                 int const X = line_size()[0];
333                 uint8_t* p = data()[0];
334                 for (int y = 0; y < Y; ++y) {
335                         for (int x = 0; x < X / 4; ++x) {
336                                 *p++ = eight_bit_uv; // Cb
337                                 *p++ = 0;            // Y0
338                                 *p++ = eight_bit_uv; // Cr
339                                 *p++ = 0;            // Y1
340                         }
341                 }
342                 break;
343         }
344
345         default:
346                 throw PixelFormatError ("make_black()", _pixel_format);
347         }
348 }
349
350 void
351 Image::make_transparent ()
352 {
353         if (_pixel_format != PIX_FMT_RGBA) {
354                 throw PixelFormatError ("make_transparent()", _pixel_format);
355         }
356
357         memset (data()[0], 0, lines(0) * stride()[0]);
358 }
359
360 void
361 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
362 {
363         DCPOMATIC_ASSERT (other->pixel_format() == PIX_FMT_RGBA);
364         int const other_bpp = 4;
365
366         int start_tx = position.x;
367         int start_ox = 0;
368
369         if (start_tx < 0) {
370                 start_ox = -start_tx;
371                 start_tx = 0;
372         }
373
374         int start_ty = position.y;
375         int start_oy = 0;
376
377         if (start_ty < 0) {
378                 start_oy = -start_ty;
379                 start_ty = 0;
380         }
381
382         switch (_pixel_format) {
383         case PIX_FMT_RGB24:
384         {
385                 int const this_bpp = 3;
386                 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
387                         uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
388                         uint8_t* op = other->data()[0] + oy * other->stride()[0];
389                         for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
390                                 float const alpha = float (op[3]) / 255;
391                                 tp[0] = op[0] * alpha + tp[0] * (1 - alpha);
392                                 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
393                                 tp[2] = op[2] * alpha + tp[2] * (1 - alpha);
394                                 
395                                 tp += this_bpp;
396                                 op += other_bpp;
397                         }
398                 }
399                 break;
400         }
401         case PIX_FMT_BGRA:
402         case PIX_FMT_RGBA:
403         {
404                 int const this_bpp = 4;
405                 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
406                         uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
407                         uint8_t* op = other->data()[0] + oy * other->stride()[0];
408                         for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
409                                 float const alpha = float (op[3]) / 255;
410                                 tp[0] = op[0] * alpha + tp[0] * (1 - alpha);
411                                 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
412                                 tp[2] = op[2] * alpha + tp[2] * (1 - alpha);
413                                 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
414                                 
415                                 tp += this_bpp;
416                                 op += other_bpp;
417                         }
418                 }
419                 break;
420         }
421         case PIX_FMT_RGB48LE:
422         {
423                 int const this_bpp = 6;
424                 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
425                         uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
426                         uint8_t* op = other->data()[0] + oy * other->stride()[0];
427                         for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
428                                 float const alpha = float (op[3]) / 255;
429                                 /* Blend high bytes */
430                                 tp[1] = op[0] * alpha + tp[1] * (1 - alpha);
431                                 tp[3] = op[1] * alpha + tp[3] * (1 - alpha);
432                                 tp[5] = op[2] * alpha + tp[5] * (1 - alpha);
433                                 
434                                 tp += this_bpp;
435                                 op += other_bpp;
436                         }
437                 }
438                 break;
439         }
440         default:
441                 DCPOMATIC_ASSERT (false);
442         }
443 }
444         
445 void
446 Image::copy (shared_ptr<const Image> other, Position<int> position)
447 {
448         /* Only implemented for RGB24 onto RGB24 so far */
449         DCPOMATIC_ASSERT (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGB24);
450         DCPOMATIC_ASSERT (position.x >= 0 && position.y >= 0);
451
452         int const N = min (position.x + other->size().width, size().width) - position.x;
453         for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
454                 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
455                 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
456                 memcpy (tp, op, N * 3);
457         }
458 }       
459
460 void
461 Image::read_from_socket (shared_ptr<Socket> socket)
462 {
463         for (int i = 0; i < components(); ++i) {
464                 uint8_t* p = data()[i];
465                 for (int y = 0; y < lines(i); ++y) {
466                         socket->read (p, line_size()[i]);
467                         p += stride()[i];
468                 }
469         }
470 }
471
472 void
473 Image::write_to_socket (shared_ptr<Socket> socket) const
474 {
475         for (int i = 0; i < components(); ++i) {
476                 uint8_t* p = data()[i];
477                 for (int y = 0; y < lines(i); ++y) {
478                         socket->write (p, line_size()[i]);
479                         p += stride()[i];
480                 }
481         }
482 }
483
484
485 float
486 Image::bytes_per_pixel (int c) const
487 {
488         AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
489         if (!d) {
490                 throw PixelFormatError ("lines()", _pixel_format);
491         }
492
493         if (c >= components()) {
494                 return 0;
495         }
496
497         float bpp[4] = { 0, 0, 0, 0 };
498
499         bpp[0] = floor ((d->comp[0].depth_minus1 + 1 + 7) / 8);
500         if (d->nb_components > 1) {
501                 bpp[1] = floor ((d->comp[1].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
502         }
503         if (d->nb_components > 2) {
504                 bpp[2] = floor ((d->comp[2].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
505         }
506         if (d->nb_components > 3) {
507                 bpp[3] = floor ((d->comp[3].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
508         }
509         
510         if ((d->flags & PIX_FMT_PLANAR) == 0) {
511                 /* Not planar; sum them up */
512                 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
513         }
514
515         return bpp[c];
516 }
517
518 /** Construct a Image of a given size and format, allocating memory
519  *  as required.
520  *
521  *  @param p Pixel format.
522  *  @param s Size in pixels.
523  */
524 Image::Image (AVPixelFormat p, dcp::Size s, bool aligned)
525         : _size (s)
526         , _pixel_format (p)
527         , _aligned (aligned)
528 {
529         allocate ();
530 }
531
532 void
533 Image::allocate ()
534 {
535         _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
536         _data[0] = _data[1] = _data[2] = _data[3] = 0;
537         
538         _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
539         _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
540         
541         _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
542         _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
543
544         for (int i = 0; i < components(); ++i) {
545                 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
546                 _stride[i] = stride_round_up (i, _line_size, _aligned ? 32 : 1);
547
548                 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
549                    uses a 16-byte fetch to read three bytes (R/G/B) of image data.
550                    Hence on the last pixel of the last line it reads over the end of
551                    the actual data by 1 byte.  If the width of an image is a multiple
552                    of the stride alignment there will be no padding at the end of image lines.
553                    OS X crashes on this illegal read, though other operating systems don't
554                    seem to mind.  The nasty + 1 in this malloc makes sure there is always a byte
555                    for that instruction to read safely.
556
557                    Further to the above, valgrind is now telling me that ff_rgb24ToY_ssse3
558                    over-reads by more then _avx.  I can't follow the code to work out how much,
559                    so I'll just over-allocate by 32 bytes and have done with it.  Empirical
560                    testing suggests that it works.
561                 */
562                 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * lines (i) + 32);
563         }
564 }
565
566 Image::Image (Image const & other)
567         : _size (other._size)
568         , _pixel_format (other._pixel_format)
569         , _aligned (other._aligned)
570 {
571         allocate ();
572
573         for (int i = 0; i < components(); ++i) {
574                 uint8_t* p = _data[i];
575                 uint8_t* q = other._data[i];
576                 for (int j = 0; j < lines(i); ++j) {
577                         memcpy (p, q, _line_size[i]);
578                         p += stride()[i];
579                         q += other.stride()[i];
580                 }
581         }
582 }
583
584 Image::Image (AVFrame* frame)
585         : _size (frame->width, frame->height)
586         , _pixel_format (static_cast<AVPixelFormat> (frame->format))
587         , _aligned (true)
588 {
589         allocate ();
590
591         for (int i = 0; i < components(); ++i) {
592                 uint8_t* p = _data[i];
593                 uint8_t* q = frame->data[i];
594                 for (int j = 0; j < lines(i); ++j) {
595                         memcpy (p, q, _line_size[i]);
596                         p += stride()[i];
597                         /* AVFrame's linesize is what we call `stride' */
598                         q += frame->linesize[i];
599                 }
600         }
601 }
602
603 Image::Image (shared_ptr<const Image> other, bool aligned)
604         : _size (other->_size)
605         , _pixel_format (other->_pixel_format)
606         , _aligned (aligned)
607 {
608         allocate ();
609
610         for (int i = 0; i < components(); ++i) {
611                 DCPOMATIC_ASSERT (line_size()[i] == other->line_size()[i]);
612                 uint8_t* p = _data[i];
613                 uint8_t* q = other->data()[i];
614                 for (int j = 0; j < lines(i); ++j) {
615                         memcpy (p, q, line_size()[i]);
616                         p += stride()[i];
617                         q += other->stride()[i];
618                 }
619         }
620 }
621
622 Image&
623 Image::operator= (Image const & other)
624 {
625         if (this == &other) {
626                 return *this;
627         }
628
629         Image tmp (other);
630         swap (tmp);
631         return *this;
632 }
633
634 void
635 Image::swap (Image & other)
636 {
637         std::swap (_size, other._size);
638         std::swap (_pixel_format, other._pixel_format);
639
640         for (int i = 0; i < 4; ++i) {
641                 std::swap (_data[i], other._data[i]);
642                 std::swap (_line_size[i], other._line_size[i]);
643                 std::swap (_stride[i], other._stride[i]);
644         }
645
646         std::swap (_aligned, other._aligned);
647 }
648
649 /** Destroy a Image */
650 Image::~Image ()
651 {
652         for (int i = 0; i < components(); ++i) {
653                 av_free (_data[i]);
654         }
655
656         av_free (_data);
657         av_free (_line_size);
658         av_free (_stride);
659 }
660
661 uint8_t * const *
662 Image::data () const
663 {
664         return _data;
665 }
666
667 int *
668 Image::line_size () const
669 {
670         return _line_size;
671 }
672
673 int const *
674 Image::stride () const
675 {
676         return _stride;
677 }
678
679 dcp::Size
680 Image::size () const
681 {
682         return _size;
683 }
684
685 bool
686 Image::aligned () const
687 {
688         return _aligned;
689 }
690
691 PositionImage
692 merge (list<PositionImage> images)
693 {
694         if (images.empty ()) {
695                 return PositionImage ();
696         }
697
698         if (images.size() == 1) {
699                 return images.front ();
700         }
701
702         dcpomatic::Rect<int> all (images.front().position, images.front().image->size().width, images.front().image->size().height);
703         for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
704                 all.extend (dcpomatic::Rect<int> (i->position, i->image->size().width, i->image->size().height));
705         }
706
707         shared_ptr<Image> merged (new Image (images.front().image->pixel_format (), dcp::Size (all.width, all.height), true));
708         merged->make_transparent ();
709         for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
710                 merged->alpha_blend (i->image, i->position - all.position());
711         }
712
713         return PositionImage (merged, all.position ());
714 }
715
716 string
717 Image::digest () const
718 {
719         MD5Digester digester;
720
721         for (int i = 0; i < components(); ++i) {
722                 digester.add (data()[i], line_size()[i]);
723         }
724
725         return digester.get ();
726 }
727
728 bool
729 operator== (Image const & a, Image const & b)
730 {
731         if (a.components() != b.components() || a.pixel_format() != b.pixel_format() || a.aligned() != b.aligned()) {
732                 return false;
733         }
734
735         for (int c = 0; c < a.components(); ++c) {
736                 if (a.lines(c) != b.lines(c) || a.line_size()[c] != b.line_size()[c] || a.stride()[c] != b.stride()[c]) {
737                         return false;
738                 }
739
740                 uint8_t* p = a.data()[c];
741                 uint8_t* q = b.data()[c];
742                 for (int y = 0; y < a.lines(c); ++y) {
743                         if (memcmp (p, q, a.line_size()[c]) != 0) {
744                                 return false;
745                         }
746
747                         p += a.stride()[c];
748                         q += b.stride()[c];
749                 }
750         }
751
752         return true;
753 }
754
755 void
756 Image::fade (float f)
757 {
758         switch (_pixel_format) {
759         case PIX_FMT_YUV420P:
760         case PIX_FMT_YUV422P:
761         case PIX_FMT_YUV444P:
762         case PIX_FMT_YUV411P:
763         case PIX_FMT_YUVJ420P:
764         case PIX_FMT_YUVJ422P:
765         case PIX_FMT_YUVJ444P:
766         case PIX_FMT_RGB24:
767         case PIX_FMT_ARGB:
768         case PIX_FMT_RGBA:
769         case PIX_FMT_ABGR:
770         case PIX_FMT_BGRA:
771         case PIX_FMT_RGB555LE:
772                 /* 8-bit */
773                 for (int c = 0; c < 3; ++c) {
774                         uint8_t* p = data()[c];
775                         for (int y = 0; y < lines(c); ++y) {
776                                 uint8_t* q = p;
777                                 for (int x = 0; x < line_size()[c]; ++x) {
778                                         *q = int (float (*q) * f);
779                                         ++q;
780                                 }
781                                 p += stride()[c];
782                         }
783                 }
784                 break;
785
786         case PIX_FMT_YUV422P9LE:
787         case PIX_FMT_YUV444P9LE:
788         case PIX_FMT_YUV422P10LE:
789         case PIX_FMT_YUV444P10LE:
790         case PIX_FMT_YUV422P16LE:
791         case PIX_FMT_YUV444P16LE:
792         case AV_PIX_FMT_YUVA420P9LE:
793         case AV_PIX_FMT_YUVA422P9LE:
794         case AV_PIX_FMT_YUVA444P9LE:
795         case AV_PIX_FMT_YUVA420P10LE:
796         case AV_PIX_FMT_YUVA422P10LE:
797         case AV_PIX_FMT_YUVA444P10LE:
798                 /* 16-bit little-endian */
799                 for (int c = 0; c < 3; ++c) {
800                         int const stride_pixels = stride()[c] / 2;
801                         int const line_size_pixels = line_size()[c] / 2;
802                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
803                         for (int y = 0; y < lines(c); ++y) {
804                                 uint16_t* q = p;
805                                 for (int x = 0; x < line_size_pixels; ++x) {
806                                         *q = int (float (*q) * f);
807                                         ++q;
808                                 }
809                                 p += stride_pixels;
810                         }
811                 }
812                 break;
813
814         case PIX_FMT_YUV422P9BE:
815         case PIX_FMT_YUV444P9BE:
816         case PIX_FMT_YUV444P10BE:
817         case PIX_FMT_YUV422P10BE:
818         case AV_PIX_FMT_YUVA420P9BE:
819         case AV_PIX_FMT_YUVA422P9BE:
820         case AV_PIX_FMT_YUVA444P9BE:
821         case AV_PIX_FMT_YUVA420P10BE:
822         case AV_PIX_FMT_YUVA422P10BE:
823         case AV_PIX_FMT_YUVA444P10BE:
824         case AV_PIX_FMT_YUVA420P16BE:
825         case AV_PIX_FMT_YUVA422P16BE:
826         case AV_PIX_FMT_YUVA444P16BE:
827                 /* 16-bit big-endian */
828                 for (int c = 0; c < 3; ++c) {
829                         int const stride_pixels = stride()[c] / 2;
830                         int const line_size_pixels = line_size()[c] / 2;
831                         uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
832                         for (int y = 0; y < lines(c); ++y) {
833                                 uint16_t* q = p;
834                                 for (int x = 0; x < line_size_pixels; ++x) {
835                                         *q = swap_16 (int (float (swap_16 (*q)) * f));
836                                         ++q;
837                                 }
838                                 p += stride_pixels;
839                         }
840                 }
841                 break;
842
843         case PIX_FMT_UYVY422:
844         {
845                 int const Y = lines(0);
846                 int const X = line_size()[0];
847                 uint8_t* p = data()[0];
848                 for (int y = 0; y < Y; ++y) {
849                         for (int x = 0; x < X; ++x) {
850                                 *p = int (float (*p) * f);
851                                 ++p;
852                         }
853                 }
854                 break;
855         }
856
857         default:
858                 throw PixelFormatError ("fade()", _pixel_format);
859         }
860 }