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