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