Make subtitles work at least a bit.
[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                 /* bytes_per_pixel() could be a fraction; in this case the stride will be rounded
218                    up, and we need to make sure that we copy over the width (up to the stride)
219                    rather than short of the width; hence the ceil() here.
220                 */
221                 int const cropped_width_in_bytes = ceil (bytes_per_pixel(c) * cropped_size.width);
222
223                 /* Start of the source line, cropped from the top but not the left */
224                 uint8_t* in_p = data()[c] + (crop.top / out->line_factor(c)) * stride()[c];
225                 uint8_t* out_p = out->data()[c];
226
227                 for (int y = 0; y < out->lines(c); ++y) {
228                         memcpy (out_p, in_p + crop_left_in_bytes, cropped_width_in_bytes);
229                         in_p += stride()[c];
230                         out_p += out->stride()[c];
231                 }
232         }
233
234         return out;
235 }
236
237 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
238 void
239 Image::yuv_16_black (uint16_t v)
240 {
241         memset (data()[0], 0, lines(0) * stride()[0]);
242         for (int i = 1; i < 3; ++i) {
243                 int16_t* p = reinterpret_cast<int16_t*> (data()[i]);
244                 for (int y = 0; y < size().height; ++y) {
245                         for (int x = 0; x < line_size()[i] / 2; ++x) {
246                                 p[x] = v;
247                         }
248                         p += stride()[i] / 2;
249                 }
250         }
251 }
252
253 uint16_t
254 Image::swap_16 (uint16_t v)
255 {
256         return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
257 }
258
259 void
260 Image::make_black ()
261 {
262         /* U/V black value for 8-bit colour */
263         static uint8_t const eight_bit_uv =     (1 << 7) - 1;
264         /* U/V black value for 9-bit colour */
265         static uint16_t const nine_bit_uv =     (1 << 8) - 1;
266         /* U/V black value for 10-bit colour */
267         static uint16_t const ten_bit_uv =      (1 << 9) - 1;
268         /* U/V black value for 16-bit colour */
269         static uint16_t const sixteen_bit_uv =  (1 << 15) - 1;
270         
271         switch (_pixel_format) {
272         case PIX_FMT_YUV420P:
273         case PIX_FMT_YUV422P:
274         case PIX_FMT_YUV444P:
275                 memset (data()[0], 0, lines(0) * stride()[0]);
276                 memset (data()[1], eight_bit_uv, lines(1) * stride()[1]);
277                 memset (data()[2], eight_bit_uv, lines(2) * stride()[2]);
278                 break;
279
280         case PIX_FMT_YUVJ420P:
281         case PIX_FMT_YUVJ422P:
282         case PIX_FMT_YUVJ444P:
283                 memset (data()[0], 0, lines(0) * stride()[0]);
284                 memset (data()[1], eight_bit_uv + 1, lines(1) * stride()[1]);
285                 memset (data()[2], eight_bit_uv + 1, lines(2) * stride()[2]);
286                 break;
287
288         case PIX_FMT_YUV422P9LE:
289         case PIX_FMT_YUV444P9LE:
290                 yuv_16_black (nine_bit_uv);
291                 break;
292
293         case PIX_FMT_YUV422P9BE:
294         case PIX_FMT_YUV444P9BE:
295                 yuv_16_black (swap_16 (nine_bit_uv));
296                 break;
297                 
298         case PIX_FMT_YUV422P10LE:
299         case PIX_FMT_YUV444P10LE:
300                 yuv_16_black (ten_bit_uv);
301                 break;
302
303         case PIX_FMT_YUV422P16LE:
304         case PIX_FMT_YUV444P16LE:
305                 yuv_16_black (sixteen_bit_uv);
306                 break;
307                 
308         case PIX_FMT_YUV444P10BE:
309         case PIX_FMT_YUV422P10BE:
310                 yuv_16_black (swap_16 (ten_bit_uv));
311                 break;
312
313         case PIX_FMT_RGB24:             
314                 memset (data()[0], 0, lines(0) * stride()[0]);
315                 break;
316
317         case PIX_FMT_UYVY422:
318         {
319                 int const Y = lines(0);
320                 int const X = line_size()[0];
321                 uint8_t* p = data()[0];
322                 for (int y = 0; y < Y; ++y) {
323                         for (int x = 0; x < X / 4; ++x) {
324                                 *p++ = eight_bit_uv; // Cb
325                                 *p++ = 0;            // Y0
326                                 *p++ = eight_bit_uv; // Cr
327                                 *p++ = 0;            // Y1
328                         }
329                 }
330                 break;
331         }
332
333         default:
334                 throw PixelFormatError (N_("make_black()"), _pixel_format);
335         }
336 }
337
338 void
339 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
340 {
341         /* Only implemented for RGBA onto RGB24 so far */
342         assert (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGBA);
343
344         int start_tx = position.x;
345         int start_ox = 0;
346
347         if (start_tx < 0) {
348                 start_ox = -start_tx;
349                 start_tx = 0;
350         }
351
352         int start_ty = position.y;
353         int start_oy = 0;
354
355         if (start_ty < 0) {
356                 start_oy = -start_ty;
357                 start_ty = 0;
358         }
359
360         for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
361                 uint8_t* tp = data()[0] + ty * stride()[0] + position.x * 3;
362                 uint8_t* op = other->data()[0] + oy * other->stride()[0];
363                 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
364                         float const alpha = float (op[3]) / 255;
365                         tp[0] = (tp[0] * (1 - alpha)) + op[0] * alpha;
366                         tp[1] = (tp[1] * (1 - alpha)) + op[1] * alpha;
367                         tp[2] = (tp[2] * (1 - alpha)) + op[2] * alpha;
368                         tp += 3;
369                         op += 4;
370                 }
371         }
372 }
373
374 void
375 Image::copy (shared_ptr<const Image> other, Position<int> position)
376 {
377         /* Only implemented for RGB24 onto RGB24 so far */
378         assert (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGB24);
379         assert (position.x >= 0 && position.y >= 0);
380
381         int const N = min (position.x + other->size().width, size().width) - position.x;
382         for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
383                 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
384                 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
385                 memcpy (tp, op, N * 3);
386         }
387 }       
388
389 void
390 Image::read_from_socket (shared_ptr<Socket> socket)
391 {
392         for (int i = 0; i < components(); ++i) {
393                 uint8_t* p = data()[i];
394                 for (int y = 0; y < lines(i); ++y) {
395                         socket->read (p, line_size()[i]);
396                         p += stride()[i];
397                 }
398         }
399 }
400
401 void
402 Image::write_to_socket (shared_ptr<Socket> socket) const
403 {
404         for (int i = 0; i < components(); ++i) {
405                 uint8_t* p = data()[i];
406                 for (int y = 0; y < lines(i); ++y) {
407                         socket->write (p, line_size()[i]);
408                         p += stride()[i];
409                 }
410         }
411 }
412
413
414 float
415 Image::bytes_per_pixel (int c) const
416 {
417         AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
418         if (!d) {
419                 throw PixelFormatError (N_("lines()"), _pixel_format);
420         }
421
422         if (c >= components()) {
423                 return 0;
424         }
425
426         float bpp[4] = { 0, 0, 0, 0 };
427
428         bpp[0] = floor ((d->comp[0].depth_minus1 + 1 + 7) / 8);
429         if (d->nb_components > 1) {
430                 bpp[1] = floor ((d->comp[1].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
431         }
432         if (d->nb_components > 2) {
433                 bpp[2] = floor ((d->comp[2].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
434         }
435         if (d->nb_components > 3) {
436                 bpp[3] = floor ((d->comp[3].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
437         }
438         
439         if ((d->flags & PIX_FMT_PLANAR) == 0) {
440                 /* Not planar; sum them up */
441                 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
442         }
443
444         return bpp[c];
445 }
446
447 /** Construct a SimpleImage of a given size and format, allocating memory
448  *  as required.
449  *
450  *  @param p Pixel format.
451  *  @param s Size in pixels.
452  */
453 SimpleImage::SimpleImage (AVPixelFormat p, libdcp::Size s, bool aligned)
454         : Image (p)
455         , _size (s)
456         , _aligned (aligned)
457 {
458         allocate ();
459 }
460
461 void
462 SimpleImage::allocate ()
463 {
464         _data = (uint8_t **) av_malloc (4 * sizeof (uint8_t *));
465         _data[0] = _data[1] = _data[2] = _data[3] = 0;
466         
467         _line_size = (int *) av_malloc (4 * sizeof (int));
468         _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
469         
470         _stride = (int *) av_malloc (4 * sizeof (int));
471         _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
472
473         for (int i = 0; i < components(); ++i) {
474                 _line_size[i] = _size.width * bytes_per_pixel(i);
475                 _stride[i] = stride_round_up (i, _line_size, _aligned ? 32 : 1);
476                 _data[i] = (uint8_t *) av_malloc (_stride[i] * lines (i));
477         }
478 }
479
480 SimpleImage::SimpleImage (SimpleImage const & other)
481         : Image (other)
482         , _size (other._size)
483         , _aligned (other._aligned)
484 {
485         allocate ();
486
487         for (int i = 0; i < components(); ++i) {
488                 uint8_t* p = _data[i];
489                 uint8_t* q = other._data[i];
490                 for (int j = 0; j < lines(i); ++j) {
491                         memcpy (p, q, _line_size[i]);
492                         p += stride()[i];
493                         q += other.stride()[i];
494                 }
495         }
496 }
497
498 SimpleImage::SimpleImage (AVFrame* frame)
499         : Image (static_cast<AVPixelFormat> (frame->format))
500         , _size (frame->width, frame->height)
501         , _aligned (true)
502 {
503         allocate ();
504
505         for (int i = 0; i < components(); ++i) {
506                 uint8_t* p = _data[i];
507                 uint8_t* q = frame->data[i];
508                 for (int j = 0; j < lines(i); ++j) {
509                         memcpy (p, q, _line_size[i]);
510                         p += stride()[i];
511                         /* AVFrame's linesize is what we call `stride' */
512                         q += frame->linesize[i];
513                 }
514         }
515 }
516
517 SimpleImage::SimpleImage (shared_ptr<const Image> other, bool aligned)
518         : Image (*other.get())
519         , _size (other->size())
520         , _aligned (aligned)
521 {
522         allocate ();
523
524         for (int i = 0; i < components(); ++i) {
525                 assert(line_size()[i] == other->line_size()[i]);
526                 uint8_t* p = _data[i];
527                 uint8_t* q = other->data()[i];
528                 for (int j = 0; j < lines(i); ++j) {
529                         memcpy (p, q, line_size()[i]);
530                         p += stride()[i];
531                         q += other->stride()[i];
532                 }
533         }
534 }
535
536 SimpleImage&
537 SimpleImage::operator= (SimpleImage const & other)
538 {
539         if (this == &other) {
540                 return *this;
541         }
542
543         SimpleImage tmp (other);
544         swap (tmp);
545         return *this;
546 }
547
548 void
549 SimpleImage::swap (SimpleImage & other)
550 {
551         Image::swap (other);
552         
553         std::swap (_size, other._size);
554
555         for (int i = 0; i < 4; ++i) {
556                 std::swap (_data[i], other._data[i]);
557                 std::swap (_line_size[i], other._line_size[i]);
558                 std::swap (_stride[i], other._stride[i]);
559         }
560
561         std::swap (_aligned, other._aligned);
562 }
563
564 /** Destroy a SimpleImage */
565 SimpleImage::~SimpleImage ()
566 {
567         for (int i = 0; i < components(); ++i) {
568                 av_free (_data[i]);
569         }
570
571         av_free (_data);
572         av_free (_line_size);
573         av_free (_stride);
574 }
575
576 uint8_t **
577 SimpleImage::data () const
578 {
579         return _data;
580 }
581
582 int *
583 SimpleImage::line_size () const
584 {
585         return _line_size;
586 }
587
588 int *
589 SimpleImage::stride () const
590 {
591         return _stride;
592 }
593
594 libdcp::Size
595 SimpleImage::size () const
596 {
597         return _size;
598 }
599
600 bool
601 SimpleImage::aligned () const
602 {
603         return _aligned;
604 }
605
606 RGBPlusAlphaImage::RGBPlusAlphaImage (shared_ptr<const Image> im)
607         : SimpleImage (im->pixel_format(), im->size(), false)
608 {
609         assert (im->pixel_format() == PIX_FMT_RGBA);
610
611         _alpha = (uint8_t *) av_malloc (im->size().width * im->size().height);
612
613         uint8_t* in = im->data()[0];
614         uint8_t* out = data()[0];
615         uint8_t* out_alpha = _alpha;
616         for (int y = 0; y < im->size().height; ++y) {
617                 uint8_t* in_r = in;
618                 for (int x = 0; x < im->size().width; ++x) {
619                         *out++ = *in_r++;
620                         *out++ = *in_r++;
621                         *out++ = *in_r++;
622                         *out_alpha++ = *in_r++;
623                 }
624
625                 in += im->stride()[0];
626         }
627 }
628
629 RGBPlusAlphaImage::~RGBPlusAlphaImage ()
630 {
631         av_free (_alpha);
632 }
633