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