Use FileGroup in FFmpeg.
[dcpomatic.git] / src / lib / image.cc
1 /*
2     Copyright (C) 2012 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 <iostream>
25 extern "C" {
26 #include <libswscale/swscale.h>
27 #include <libavutil/pixfmt.h>
28 #include <libavutil/pixdesc.h>
29 #include <libpostproc/postprocess.h>
30 }
31 #include "image.h"
32 #include "exceptions.h"
33 #include "scaler.h"
34
35 using std::string;
36 using std::min;
37 using std::cout;
38 using boost::shared_ptr;
39 using libdcp::Size;
40
41 int
42 Image::line_factor (int n) const
43 {
44         if (n == 0) {
45                 return 1;
46         }
47
48         AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
49         if (!d) {
50                 throw PixelFormatError ("lines()", _pixel_format);
51         }
52         
53         return pow (2.0f, d->log2_chroma_h);
54 }
55
56 /** @param n Component index.
57  *  @return Number of lines in the image for the given component.
58  */
59 int
60 Image::lines (int n) const
61 {
62         return rint (ceil (static_cast<double>(size().height) / line_factor (n)));
63 }
64
65 /** @return Number of components */
66 int
67 Image::components () const
68 {
69         AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
70         if (!d) {
71                 throw PixelFormatError ("components()", _pixel_format);
72         }
73
74         if ((d->flags & PIX_FMT_PLANAR) == 0) {
75                 return 1;
76         }
77         
78         return d->nb_components;
79 }
80
81 shared_ptr<Image>
82 Image::scale (libdcp::Size out_size, Scaler const * scaler, AVPixelFormat result_format, bool result_aligned) const
83 {
84         assert (scaler);
85         /* Empirical testing suggests that sws_scale() will crash if
86            the input image is not aligned.
87         */
88         assert (aligned ());
89
90         shared_ptr<Image> scaled (new Image (result_format, out_size, result_aligned));
91
92         struct SwsContext* scale_context = sws_getContext (
93                 size().width, size().height, pixel_format(),
94                 out_size.width, out_size.height, result_format,
95                 scaler->ffmpeg_id (), 0, 0, 0
96                 );
97
98         sws_scale (
99                 scale_context,
100                 data(), stride(),
101                 0, size().height,
102                 scaled->data(), scaled->stride()
103                 );
104
105         sws_freeContext (scale_context);
106
107         return scaled;
108 }
109
110 /** Run a FFmpeg post-process on this image and return the processed version.
111  *  @param pp Flags for the required set of post processes.
112  *  @return Post-processed image.
113  */
114 shared_ptr<Image>
115 Image::post_process (string pp, bool aligned) const
116 {
117         shared_ptr<Image> out (new Image (pixel_format(), size (), aligned));
118
119         int pp_format = 0;
120         switch (pixel_format()) {
121         case PIX_FMT_YUV420P:
122                 pp_format = PP_FORMAT_420;
123                 break;
124         case PIX_FMT_YUV422P10LE:
125         case PIX_FMT_YUV422P:
126         case PIX_FMT_UYVY422:
127                 pp_format = PP_FORMAT_422;
128                 break;
129         case PIX_FMT_YUV444P:
130         case PIX_FMT_YUV444P9BE:
131         case PIX_FMT_YUV444P9LE:
132         case PIX_FMT_YUV444P10BE:
133         case PIX_FMT_YUV444P10LE:
134                 pp_format = PP_FORMAT_444;
135         default:
136                 throw PixelFormatError ("post_process", pixel_format());
137         }
138                 
139         pp_mode* mode = pp_get_mode_by_name_and_quality (pp.c_str (), PP_QUALITY_MAX);
140         pp_context* context = pp_get_context (size().width, size().height, pp_format | PP_CPU_CAPS_MMX2);
141
142         pp_postprocess (
143                 (const uint8_t **) data(), stride(),
144                 out->data(), out->stride(),
145                 size().width, size().height,
146                 0, 0, mode, context, 0
147                 );
148                 
149         pp_free_mode (mode);
150         pp_free_context (context);
151
152         return out;
153 }
154
155 shared_ptr<Image>
156 Image::crop (Crop crop, bool aligned) const
157 {
158         libdcp::Size cropped_size = crop.apply (size ());
159         shared_ptr<Image> out (new Image (pixel_format(), cropped_size, aligned));
160
161         for (int c = 0; c < components(); ++c) {
162                 int const crop_left_in_bytes = bytes_per_pixel(c) * crop.left;
163                 /* bytes_per_pixel() could be a fraction; in this case the stride will be rounded
164                    up, and we need to make sure that we copy over the width (up to the stride)
165                    rather than short of the width; hence the ceil() here.
166                 */
167                 int const cropped_width_in_bytes = ceil (bytes_per_pixel(c) * cropped_size.width);
168
169                 /* Start of the source line, cropped from the top but not the left */
170                 uint8_t* in_p = data()[c] + (crop.top / out->line_factor(c)) * stride()[c];
171                 uint8_t* out_p = out->data()[c];
172
173                 for (int y = 0; y < out->lines(c); ++y) {
174                         memcpy (out_p, in_p + crop_left_in_bytes, cropped_width_in_bytes);
175                         in_p += stride()[c];
176                         out_p += out->stride()[c];
177                 }
178         }
179
180         return out;
181 }
182
183 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
184 void
185 Image::yuv_16_black (uint16_t v, bool alpha)
186 {
187         memset (data()[0], 0, lines(0) * stride()[0]);
188         for (int i = 1; i < 3; ++i) {
189                 int16_t* p = reinterpret_cast<int16_t*> (data()[i]);
190                 for (int y = 0; y < lines(i); ++y) {
191                         /* We divide by 2 here because we are writing 2 bytes at a time */
192                         for (int x = 0; x < line_size()[i] / 2; ++x) {
193                                 p[x] = v;
194                         }
195                         p += stride()[i] / 2;
196                 }
197         }
198
199         if (alpha) {
200                 memset (data()[3], 0, lines(3) * stride()[3]);
201         }
202 }
203
204 uint16_t
205 Image::swap_16 (uint16_t v)
206 {
207         return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
208 }
209
210 void
211 Image::make_black ()
212 {
213         /* U/V black value for 8-bit colour */
214         static uint8_t const eight_bit_uv =     (1 << 7) - 1;
215         /* U/V black value for 9-bit colour */
216         static uint16_t const nine_bit_uv =     (1 << 8) - 1;
217         /* U/V black value for 10-bit colour */
218         static uint16_t const ten_bit_uv =      (1 << 9) - 1;
219         /* U/V black value for 16-bit colour */
220         static uint16_t const sixteen_bit_uv =  (1 << 15) - 1;
221         
222         switch (_pixel_format) {
223         case PIX_FMT_YUV420P:
224         case PIX_FMT_YUV422P:
225         case PIX_FMT_YUV444P:
226                 memset (data()[0], 0, lines(0) * stride()[0]);
227                 memset (data()[1], eight_bit_uv, lines(1) * stride()[1]);
228                 memset (data()[2], eight_bit_uv, lines(2) * stride()[2]);
229                 break;
230
231         case PIX_FMT_YUVJ420P:
232         case PIX_FMT_YUVJ422P:
233         case PIX_FMT_YUVJ444P:
234                 memset (data()[0], 0, lines(0) * stride()[0]);
235                 memset (data()[1], eight_bit_uv + 1, lines(1) * stride()[1]);
236                 memset (data()[2], eight_bit_uv + 1, lines(2) * stride()[2]);
237                 break;
238
239         case PIX_FMT_YUV422P9LE:
240         case PIX_FMT_YUV444P9LE:
241                 yuv_16_black (nine_bit_uv, false);
242                 break;
243
244         case PIX_FMT_YUV422P9BE:
245         case PIX_FMT_YUV444P9BE:
246                 yuv_16_black (swap_16 (nine_bit_uv), false);
247                 break;
248                 
249         case PIX_FMT_YUV422P10LE:
250         case PIX_FMT_YUV444P10LE:
251                 yuv_16_black (ten_bit_uv, false);
252                 break;
253
254         case PIX_FMT_YUV422P16LE:
255         case PIX_FMT_YUV444P16LE:
256                 yuv_16_black (sixteen_bit_uv, false);
257                 break;
258                 
259         case PIX_FMT_YUV444P10BE:
260         case PIX_FMT_YUV422P10BE:
261                 yuv_16_black (swap_16 (ten_bit_uv), false);
262                 break;
263
264         case AV_PIX_FMT_YUVA420P9BE:
265         case AV_PIX_FMT_YUVA422P9BE:
266         case AV_PIX_FMT_YUVA444P9BE:
267                 yuv_16_black (swap_16 (nine_bit_uv), true);
268                 break;
269                 
270         case AV_PIX_FMT_YUVA420P9LE:
271         case AV_PIX_FMT_YUVA422P9LE:
272         case AV_PIX_FMT_YUVA444P9LE:
273                 yuv_16_black (nine_bit_uv, true);
274                 break;
275                 
276         case AV_PIX_FMT_YUVA420P10BE:
277         case AV_PIX_FMT_YUVA422P10BE:
278         case AV_PIX_FMT_YUVA444P10BE:
279                 yuv_16_black (swap_16 (ten_bit_uv), true);
280                 break;
281                 
282         case AV_PIX_FMT_YUVA420P10LE:
283         case AV_PIX_FMT_YUVA422P10LE:
284         case AV_PIX_FMT_YUVA444P10LE:
285                 yuv_16_black (ten_bit_uv, true);
286                 break;
287                 
288         case AV_PIX_FMT_YUVA420P16BE:
289         case AV_PIX_FMT_YUVA422P16BE:
290         case AV_PIX_FMT_YUVA444P16BE:
291                 yuv_16_black (swap_16 (sixteen_bit_uv), true);
292                 break;
293                 
294         case AV_PIX_FMT_YUVA420P16LE:
295         case AV_PIX_FMT_YUVA422P16LE:
296         case AV_PIX_FMT_YUVA444P16LE:
297                 yuv_16_black (sixteen_bit_uv, true);
298                 break;
299
300         case PIX_FMT_RGB24:
301         case PIX_FMT_ARGB:
302         case PIX_FMT_RGBA:
303         case PIX_FMT_ABGR:
304         case PIX_FMT_BGRA:
305                 memset (data()[0], 0, lines(0) * stride()[0]);
306                 break;
307
308         case PIX_FMT_UYVY422:
309         {
310                 int const Y = lines(0);
311                 int const X = line_size()[0];
312                 uint8_t* p = data()[0];
313                 for (int y = 0; y < Y; ++y) {
314                         for (int x = 0; x < X / 4; ++x) {
315                                 *p++ = eight_bit_uv; // Cb
316                                 *p++ = 0;            // Y0
317                                 *p++ = eight_bit_uv; // Cr
318                                 *p++ = 0;            // Y1
319                         }
320                 }
321                 break;
322         }
323
324         default:
325                 throw PixelFormatError ("make_black()", _pixel_format);
326         }
327 }
328
329 void
330 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
331 {
332         /* Only implemented for RGBA onto RGB24 so far */
333         assert (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGBA);
334
335         int start_tx = position.x;
336         int start_ox = 0;
337
338         if (start_tx < 0) {
339                 start_ox = -start_tx;
340                 start_tx = 0;
341         }
342
343         int start_ty = position.y;
344         int start_oy = 0;
345
346         if (start_ty < 0) {
347                 start_oy = -start_ty;
348                 start_ty = 0;
349         }
350
351         for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
352                 uint8_t* tp = data()[0] + ty * stride()[0] + position.x * 3;
353                 uint8_t* op = other->data()[0] + oy * other->stride()[0];
354                 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
355                         float const alpha = float (op[3]) / 255;
356                         tp[0] = (tp[0] * (1 - alpha)) + op[0] * alpha;
357                         tp[1] = (tp[1] * (1 - alpha)) + op[1] * alpha;
358                         tp[2] = (tp[2] * (1 - alpha)) + op[2] * alpha;
359                         tp += 3;
360                         op += 4;
361                 }
362         }
363 }
364
365 void
366 Image::copy (shared_ptr<const Image> other, Position<int> position)
367 {
368         /* Only implemented for RGB24 onto RGB24 so far */
369         assert (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGB24);
370         assert (position.x >= 0 && position.y >= 0);
371
372         int const N = min (position.x + other->size().width, size().width) - position.x;
373         for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
374                 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
375                 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
376                 memcpy (tp, op, N * 3);
377         }
378 }       
379
380 void
381 Image::read_from_socket (shared_ptr<Socket> socket)
382 {
383         for (int i = 0; i < components(); ++i) {
384                 uint8_t* p = data()[i];
385                 for (int y = 0; y < lines(i); ++y) {
386                         socket->read (p, line_size()[i]);
387                         p += stride()[i];
388                 }
389         }
390 }
391
392 void
393 Image::write_to_socket (shared_ptr<Socket> socket) const
394 {
395         for (int i = 0; i < components(); ++i) {
396                 uint8_t* p = data()[i];
397                 for (int y = 0; y < lines(i); ++y) {
398                         socket->write (p, line_size()[i]);
399                         p += stride()[i];
400                 }
401         }
402 }
403
404
405 float
406 Image::bytes_per_pixel (int c) const
407 {
408         AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
409         if (!d) {
410                 throw PixelFormatError ("lines()", _pixel_format);
411         }
412
413         if (c >= components()) {
414                 return 0;
415         }
416
417         float bpp[4] = { 0, 0, 0, 0 };
418
419         bpp[0] = floor ((d->comp[0].depth_minus1 + 1 + 7) / 8);
420         if (d->nb_components > 1) {
421                 bpp[1] = floor ((d->comp[1].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
422         }
423         if (d->nb_components > 2) {
424                 bpp[2] = floor ((d->comp[2].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
425         }
426         if (d->nb_components > 3) {
427                 bpp[3] = floor ((d->comp[3].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
428         }
429         
430         if ((d->flags & PIX_FMT_PLANAR) == 0) {
431                 /* Not planar; sum them up */
432                 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
433         }
434
435         return bpp[c];
436 }
437
438 /** Construct a Image of a given size and format, allocating memory
439  *  as required.
440  *
441  *  @param p Pixel format.
442  *  @param s Size in pixels.
443  */
444 Image::Image (AVPixelFormat p, libdcp::Size s, bool aligned)
445         : libdcp::Image (s)
446         , _pixel_format (p)
447         , _aligned (aligned)
448 {
449         allocate ();
450 }
451
452 void
453 Image::allocate ()
454 {
455         _data = (uint8_t **) av_malloc (4 * sizeof (uint8_t *));
456         _data[0] = _data[1] = _data[2] = _data[3] = 0;
457         
458         _line_size = (int *) av_malloc (4 * sizeof (int));
459         _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
460         
461         _stride = (int *) av_malloc (4 * sizeof (int));
462         _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
463
464         for (int i = 0; i < components(); ++i) {
465                 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
466                 _stride[i] = stride_round_up (i, _line_size, _aligned ? 32 : 1);
467
468                 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
469                    uses a 16-byte fetch to read three bytes (R/G/B) of image data.
470                    Hence on the last pixel of the last line it reads over the end of
471                    the actual data by 1 byte.  If the width of an image is a multiple
472                    of the stride alignment there will be no padding at the end of image lines.
473                    OS X crashes on this illegal read, though other operating systems don't
474                    seem to mind.  The nasty + 1 in this malloc makes sure there is always a byte
475                    for that instruction to read safely.
476                 */
477                 _data[i] = (uint8_t *) av_malloc (_stride[i] * lines (i) + 1);
478         }
479 }
480
481 Image::Image (Image const & other)
482         : libdcp::Image (other)
483         ,  _pixel_format (other._pixel_format)
484         , _aligned (other._aligned)
485 {
486         allocate ();
487
488         for (int i = 0; i < components(); ++i) {
489                 uint8_t* p = _data[i];
490                 uint8_t* q = other._data[i];
491                 for (int j = 0; j < lines(i); ++j) {
492                         memcpy (p, q, _line_size[i]);
493                         p += stride()[i];
494                         q += other.stride()[i];
495                 }
496         }
497 }
498
499 Image::Image (AVFrame* frame)
500         : libdcp::Image (libdcp::Size (frame->width, frame->height))
501         , _pixel_format (static_cast<AVPixelFormat> (frame->format))
502         , _aligned (true)
503 {
504         allocate ();
505
506         for (int i = 0; i < components(); ++i) {
507                 uint8_t* p = _data[i];
508                 uint8_t* q = frame->data[i];
509                 for (int j = 0; j < lines(i); ++j) {
510                         memcpy (p, q, _line_size[i]);
511                         p += stride()[i];
512                         /* AVFrame's linesize is what we call `stride' */
513                         q += frame->linesize[i];
514                 }
515         }
516 }
517
518 Image::Image (shared_ptr<const Image> other, bool aligned)
519         : libdcp::Image (other)
520         , _pixel_format (other->_pixel_format)
521         , _aligned (aligned)
522 {
523         allocate ();
524
525         for (int i = 0; i < components(); ++i) {
526                 assert(line_size()[i] == other->line_size()[i]);
527                 uint8_t* p = _data[i];
528                 uint8_t* q = other->data()[i];
529                 for (int j = 0; j < lines(i); ++j) {
530                         memcpy (p, q, line_size()[i]);
531                         p += stride()[i];
532                         q += other->stride()[i];
533                 }
534         }
535 }
536
537 Image&
538 Image::operator= (Image const & other)
539 {
540         if (this == &other) {
541                 return *this;
542         }
543
544         Image tmp (other);
545         swap (tmp);
546         return *this;
547 }
548
549 void
550 Image::swap (Image & other)
551 {
552         libdcp::Image::swap (other);
553         
554         std::swap (_pixel_format, other._pixel_format);
555
556         for (int i = 0; i < 4; ++i) {
557                 std::swap (_data[i], other._data[i]);
558                 std::swap (_line_size[i], other._line_size[i]);
559                 std::swap (_stride[i], other._stride[i]);
560         }
561
562         std::swap (_aligned, other._aligned);
563 }
564
565 /** Destroy a Image */
566 Image::~Image ()
567 {
568         for (int i = 0; i < components(); ++i) {
569                 av_free (_data[i]);
570         }
571
572         av_free (_data);
573         av_free (_line_size);
574         av_free (_stride);
575 }
576
577 uint8_t **
578 Image::data () const
579 {
580         return _data;
581 }
582
583 int *
584 Image::line_size () const
585 {
586         return _line_size;
587 }
588
589 int *
590 Image::stride () const
591 {
592         return _stride;
593 }
594
595 libdcp::Size
596 Image::size () const
597 {
598         return _size;
599 }
600
601 bool
602 Image::aligned () const
603 {
604         return _aligned;
605 }
606