More pixel formats.
[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 }
39 #include "image.h"
40 #include "exceptions.h"
41 #include "scaler.h"
42
43 #include "i18n.h"
44
45 using namespace std;
46 using namespace boost;
47 using libdcp::Size;
48
49 void
50 Image::swap (Image& other)
51 {
52         std::swap (_pixel_format, other._pixel_format);
53 }
54
55 /** @param n Component index.
56  *  @return Number of lines in the image for the given component.
57  */
58 int
59 Image::lines (int n) const
60 {
61         switch (_pixel_format) {
62         case PIX_FMT_YUV420P:
63                 if (n == 0) {
64                         return size().height;
65                 } else {
66                         return size().height / 2;
67                 }
68                 break;
69         case PIX_FMT_RGB24:
70         case PIX_FMT_RGBA:
71         case PIX_FMT_YUV422P:
72         case PIX_FMT_YUV422P10LE:
73         case PIX_FMT_YUV422P16LE:
74         case PIX_FMT_YUV422P16BE:
75         case PIX_FMT_YUV444P:
76         case PIX_FMT_YUV444P9BE:
77         case PIX_FMT_YUV444P9LE:
78         case PIX_FMT_YUV444P10BE:
79         case PIX_FMT_YUV444P10LE:
80         case PIX_FMT_UYVY422:
81                 return size().height;
82         default:
83                 throw PixelFormatError (N_("lines()"), _pixel_format);
84         }
85
86         return 0;
87 }
88
89 /** @return Number of components */
90 int
91 Image::components () const
92 {
93         switch (_pixel_format) {
94         case PIX_FMT_YUV420P:
95         case PIX_FMT_YUV422P9BE:
96         case PIX_FMT_YUV422P9LE:
97         case PIX_FMT_YUV422P10BE:
98         case PIX_FMT_YUV422P10LE:
99         case PIX_FMT_YUV422P16LE:
100         case PIX_FMT_YUV422P16BE:
101         case PIX_FMT_YUV422P:
102         case PIX_FMT_YUV444P:
103         case PIX_FMT_YUV444P9BE:
104         case PIX_FMT_YUV444P9LE:
105         case PIX_FMT_YUV444P10BE:
106         case PIX_FMT_YUV444P10LE:
107         case PIX_FMT_YUV444P16LE:
108         case PIX_FMT_YUV444P16BE:
109                 return 3;
110         case PIX_FMT_RGB24:
111         case PIX_FMT_RGBA:
112         case PIX_FMT_UYVY422:
113                 return 1;
114         default:
115                 throw PixelFormatError (N_("components()"), _pixel_format);
116         }
117
118         return 0;
119 }
120
121 shared_ptr<Image>
122 Image::scale (libdcp::Size out_size, Scaler const * scaler, bool result_aligned) const
123 {
124         assert (scaler);
125         /* Empirical testing suggests that sws_scale() will crash if
126            the input image is not aligned.
127         */
128         assert (aligned ());
129
130         shared_ptr<Image> scaled (new SimpleImage (pixel_format(), out_size, result_aligned));
131
132         struct SwsContext* scale_context = sws_getContext (
133                 size().width, size().height, pixel_format(),
134                 out_size.width, out_size.height, pixel_format(),
135                 scaler->ffmpeg_id (), 0, 0, 0
136                 );
137
138         sws_scale (
139                 scale_context,
140                 data(), stride(),
141                 0, size().height,
142                 scaled->data(), scaled->stride()
143                 );
144
145         sws_freeContext (scale_context);
146
147         return scaled;
148 }
149
150 /** Scale this image to a given size and convert it to RGB.
151  *  @param out_size Output image size in pixels.
152  *  @param scaler Scaler to use.
153  */
154 shared_ptr<Image>
155 Image::scale_and_convert_to_rgb (libdcp::Size out_size, int padding, Scaler const * scaler, bool result_aligned) const
156 {
157         assert (scaler);
158         /* Empirical testing suggests that sws_scale() will crash if
159            the input image is not aligned.
160         */
161         assert (aligned ());
162
163         libdcp::Size content_size = out_size;
164         content_size.width -= (padding * 2);
165
166         shared_ptr<Image> rgb (new SimpleImage (PIX_FMT_RGB24, content_size, result_aligned));
167
168         struct SwsContext* scale_context = sws_getContext (
169                 size().width, size().height, pixel_format(),
170                 content_size.width, content_size.height, PIX_FMT_RGB24,
171                 scaler->ffmpeg_id (), 0, 0, 0
172                 );
173
174         /* Scale and convert to RGB from whatever its currently in (which may be RGB) */
175         sws_scale (
176                 scale_context,
177                 data(), stride(),
178                 0, size().height,
179                 rgb->data(), rgb->stride()
180                 );
181
182         /* Put the image in the right place in a black frame if are padding; this is
183            a bit grubby and expensive, but probably inconsequential in the great
184            scheme of things.
185         */
186         if (padding > 0) {
187                 shared_ptr<Image> padded_rgb (new SimpleImage (PIX_FMT_RGB24, out_size, result_aligned));
188                 padded_rgb->make_black ();
189
190                 /* XXX: we are cheating a bit here; we know the frame is RGB so we can
191                    make assumptions about its composition.
192                 */
193                 uint8_t* p = padded_rgb->data()[0] + padding * 3;
194                 uint8_t* q = rgb->data()[0];
195                 for (int j = 0; j < rgb->lines(0); ++j) {
196                         memcpy (p, q, rgb->line_size()[0]);
197                         p += padded_rgb->stride()[0];
198                         q += rgb->stride()[0];
199                 }
200
201                 rgb = padded_rgb;
202         }
203
204         sws_freeContext (scale_context);
205
206         return rgb;
207 }
208
209 /** Run a FFmpeg post-process on this image and return the processed version.
210  *  @param pp Flags for the required set of post processes.
211  *  @return Post-processed image.
212  */
213 shared_ptr<Image>
214 Image::post_process (string pp, bool aligned) const
215 {
216         shared_ptr<Image> out (new SimpleImage (pixel_format(), size (), aligned));
217
218         int pp_format = 0;
219         switch (pixel_format()) {
220         case PIX_FMT_YUV420P:
221                 pp_format = PP_FORMAT_420;
222                 break;
223         case PIX_FMT_YUV422P10LE:
224         case PIX_FMT_YUV422P:
225         case PIX_FMT_UYVY422:
226                 pp_format = PP_FORMAT_422;
227                 break;
228         case PIX_FMT_YUV444P:
229         case PIX_FMT_YUV444P9BE:
230         case PIX_FMT_YUV444P9LE:
231         case PIX_FMT_YUV444P10BE:
232         case PIX_FMT_YUV444P10LE:
233                 pp_format = PP_FORMAT_444;
234         default:
235                 throw PixelFormatError (N_("post_process"), pixel_format());
236         }
237                 
238         pp_mode* mode = pp_get_mode_by_name_and_quality (pp.c_str (), PP_QUALITY_MAX);
239         pp_context* context = pp_get_context (size().width, size().height, pp_format | PP_CPU_CAPS_MMX2);
240
241         pp_postprocess (
242                 (const uint8_t **) data(), stride(),
243                 out->data(), out->stride(),
244                 size().width, size().height,
245                 0, 0, mode, context, 0
246                 );
247                 
248         pp_free_mode (mode);
249         pp_free_context (context);
250
251         return out;
252 }
253
254 shared_ptr<Image>
255 Image::crop (Crop crop, bool aligned) const
256 {
257         libdcp::Size cropped_size = size ();
258         cropped_size.width -= crop.left + crop.right;
259         cropped_size.height -= crop.top + crop.bottom;
260
261         shared_ptr<Image> out (new SimpleImage (pixel_format(), cropped_size, aligned));
262
263         for (int c = 0; c < components(); ++c) {
264                 int const crop_left_in_bytes = bytes_per_pixel(c) * crop.left;
265                 int const cropped_width_in_bytes = bytes_per_pixel(c) * cropped_size.width;
266                         
267                 /* Start of the source line, cropped from the top but not the left */
268                 uint8_t* in_p = data()[c] + crop.top * stride()[c];
269                 uint8_t* out_p = out->data()[c];
270                 
271                 for (int y = 0; y < cropped_size.height; ++y) {
272                         memcpy (out_p, in_p + crop_left_in_bytes, cropped_width_in_bytes);
273                         in_p += stride()[c];
274                         out_p += out->stride()[c];
275                 }
276         }
277
278         return out;
279 }
280
281 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
282 void
283 Image::yuv_16_black (uint16_t v)
284 {
285         memset (data()[0], 0, lines(0) * stride()[0]);
286         for (int i = 1; i < 3; ++i) {
287                 int16_t* p = reinterpret_cast<int16_t*> (data()[i]);
288                 for (int y = 0; y < size().height; ++y) {
289                         for (int x = 0; x < line_size()[i] / 2; ++x) {
290                                 p[x] = v;
291                         }
292                         p += stride()[i] / 2;
293                 }
294         }
295 }
296
297 uint16_t
298 Image::swap_16 (uint16_t v)
299 {
300         return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
301 }
302
303 void
304 Image::make_black ()
305 {
306         /* U/V black value for 8-bit colour */
307         static uint8_t const eight_bit_uv = (1 << 7) - 1;
308         
309         /* U/V black value for 9-bit colour */
310         static uint16_t const nine_bit_uv = (1 << 8) - 1;
311
312         /* U/V black value for 10-bit colour */
313         static uint16_t const ten_bit_uv =  (1 << 9) - 1;
314         
315         switch (_pixel_format) {
316         case PIX_FMT_YUV420P:
317         case PIX_FMT_YUV422P:
318         case PIX_FMT_YUV444P:
319                 memset (data()[0], 0, lines(0) * stride()[0]);
320                 memset (data()[1], eight_bit_uv, lines(1) * stride()[1]);
321                 memset (data()[2], eight_bit_uv, lines(2) * stride()[2]);
322                 break;
323
324         case PIX_FMT_YUV422P9LE:
325         case PIX_FMT_YUV444P9LE:
326                 yuv_16_black (nine_bit_uv);
327                 break;
328
329         case PIX_FMT_YUV422P9BE:
330         case PIX_FMT_YUV444P9BE:
331                 yuv_16_black (swap_16 (nine_bit_uv));
332                 break;
333                 
334         case PIX_FMT_YUV422P10LE:
335         case PIX_FMT_YUV444P10LE:
336                 yuv_16_black (ten_bit_uv);
337                 break;
338                 
339         case PIX_FMT_YUV444P10BE:
340         case PIX_FMT_YUV422P10BE:
341                 yuv_16_black (swap_16 (ten_bit_uv));
342                 
343         case PIX_FMT_RGB24:             
344                 memset (data()[0], 0, lines(0) * stride()[0]);
345                 break;
346
347         case PIX_FMT_UYVY422:
348         {
349                 int const Y = lines(0);
350                 int const X = line_size()[0];
351                 uint8_t* p = data()[0];
352                 for (int y = 0; y < Y; ++y) {
353                         for (int x = 0; x < X / 4; ++x) {
354                                 *p++ = eight_bit_uv; // Cb
355                                 *p++ = 0;            // Y0
356                                 *p++ = eight_bit_uv; // Cr
357                                 *p++ = 0;            // Y1
358                         }
359                 }
360                 break;
361         }
362
363         default:
364                 throw PixelFormatError (N_("make_black()"), _pixel_format);
365         }
366 }
367
368 void
369 Image::alpha_blend (shared_ptr<const Image> other, Position position)
370 {
371         /* Only implemented for RGBA onto RGB24 so far */
372         assert (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGBA);
373
374         int start_tx = position.x;
375         int start_ox = 0;
376
377         if (start_tx < 0) {
378                 start_ox = -start_tx;
379                 start_tx = 0;
380         }
381
382         int start_ty = position.y;
383         int start_oy = 0;
384
385         if (start_ty < 0) {
386                 start_oy = -start_ty;
387                 start_ty = 0;
388         }
389
390         for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
391                 uint8_t* tp = data()[0] + ty * stride()[0] + position.x * 3;
392                 uint8_t* op = other->data()[0] + oy * other->stride()[0];
393                 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
394                         float const alpha = float (op[3]) / 255;
395                         tp[0] = (tp[0] * (1 - alpha)) + op[0] * alpha;
396                         tp[1] = (tp[1] * (1 - alpha)) + op[1] * alpha;
397                         tp[2] = (tp[2] * (1 - alpha)) + op[2] * alpha;
398                         tp += 3;
399                         op += 4;
400                 }
401         }
402 }
403
404 void
405 Image::read_from_socket (shared_ptr<Socket> socket)
406 {
407         for (int i = 0; i < components(); ++i) {
408                 uint8_t* p = data()[i];
409                 for (int y = 0; y < lines(i); ++y) {
410                         socket->read (p, line_size()[i]);
411                         p += stride()[i];
412                 }
413         }
414 }
415
416 void
417 Image::write_to_socket (shared_ptr<Socket> socket) const
418 {
419         for (int i = 0; i < components(); ++i) {
420                 uint8_t* p = data()[i];
421                 for (int y = 0; y < lines(i); ++y) {
422                         socket->write (p, line_size()[i]);
423                         p += stride()[i];
424                 }
425         }
426 }
427
428
429 float
430 Image::bytes_per_pixel (int c) const
431 {
432         if (c == 3) {
433                 return 0;
434         }
435         
436         switch (_pixel_format) {
437         case PIX_FMT_RGB24:
438                 if (c == 0) {
439                         return 3;
440                 } else {
441                         return 0;
442                 }
443         case PIX_FMT_RGBA:
444                 if (c == 0) {
445                         return 4;
446                 } else {
447                         return 0;
448                 }
449         case PIX_FMT_YUV420P:
450         case PIX_FMT_YUV422P:
451                 if (c == 0) {
452                         return 1;
453                 } else {
454                         return 0.5;
455                 }
456         case PIX_FMT_YUV422P10LE:
457         case PIX_FMT_YUV422P16LE:
458                 if (c == 0) {
459                         return 2;
460                 } else {
461                         return 1;
462                 }
463         case PIX_FMT_UYVY422:
464                 return 2;
465         case PIX_FMT_YUV444P:
466                 return 3;
467         case PIX_FMT_YUV444P9BE:
468         case PIX_FMT_YUV444P9LE:
469         case PIX_FMT_YUV444P10LE:
470         case PIX_FMT_YUV444P10BE:
471                 return 6;
472         default:
473                 throw PixelFormatError (N_("bytes_per_pixel()"), _pixel_format);
474         }
475
476         return 0;
477 }
478
479
480 /** Construct a SimpleImage of a given size and format, allocating memory
481  *  as required.
482  *
483  *  @param p Pixel format.
484  *  @param s Size in pixels.
485  */
486 SimpleImage::SimpleImage (AVPixelFormat p, libdcp::Size s, bool aligned)
487         : Image (p)
488         , _size (s)
489         , _aligned (aligned)
490 {
491         allocate ();
492 }
493
494 void
495 SimpleImage::allocate ()
496 {
497         _data = (uint8_t **) av_malloc (4 * sizeof (uint8_t *));
498         _data[0] = _data[1] = _data[2] = _data[3] = 0;
499         
500         _line_size = (int *) av_malloc (4 * sizeof (int));
501         _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
502         
503         _stride = (int *) av_malloc (4 * sizeof (int));
504         _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
505
506         for (int i = 0; i < components(); ++i) {
507                 _line_size[i] = _size.width * bytes_per_pixel(i);
508                 _stride[i] = stride_round_up (i, _line_size, _aligned ? 32 : 1);
509                 _data[i] = (uint8_t *) av_malloc (_stride[i] * lines (i));
510         }
511 }
512
513 SimpleImage::SimpleImage (SimpleImage const & other)
514         : Image (other)
515 {
516         _size = other._size;
517         _aligned = other._aligned;
518         
519         allocate ();
520
521         for (int i = 0; i < components(); ++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::SimpleImage (shared_ptr<const Image> other)
533         : Image (*other.get())
534 {
535         _size = other->size ();
536         _aligned = true;
537
538         allocate ();
539
540         for (int i = 0; i < components(); ++i) {
541                 assert(line_size()[i] == other->line_size()[i]);
542                 uint8_t* p = _data[i];
543                 uint8_t* q = other->data()[i];
544                 for (int j = 0; j < lines(i); ++j) {
545                         memcpy (p, q, line_size()[i]);
546                         p += stride()[i];
547                         q += other->stride()[i];
548                 }
549         }
550 }
551
552 SimpleImage&
553 SimpleImage::operator= (SimpleImage const & other)
554 {
555         if (this == &other) {
556                 return *this;
557         }
558
559         SimpleImage tmp (other);
560         swap (tmp);
561         return *this;
562 }
563
564 void
565 SimpleImage::swap (SimpleImage & other)
566 {
567         Image::swap (other);
568         
569         std::swap (_size, other._size);
570
571         for (int i = 0; i < 4; ++i) {
572                 std::swap (_data[i], other._data[i]);
573                 std::swap (_line_size[i], other._line_size[i]);
574                 std::swap (_stride[i], other._stride[i]);
575         }
576
577         std::swap (_aligned, other._aligned);
578 }
579
580 /** Destroy a SimpleImage */
581 SimpleImage::~SimpleImage ()
582 {
583         for (int i = 0; i < components(); ++i) {
584                 av_free (_data[i]);
585         }
586
587         av_free (_data);
588         av_free (_line_size);
589         av_free (_stride);
590 }
591
592 uint8_t **
593 SimpleImage::data () const
594 {
595         return _data;
596 }
597
598 int *
599 SimpleImage::line_size () const
600 {
601         return _line_size;
602 }
603
604 int *
605 SimpleImage::stride () const
606 {
607         return _stride;
608 }
609
610 libdcp::Size
611 SimpleImage::size () const
612 {
613         return _size;
614 }
615
616 bool
617 SimpleImage::aligned () const
618 {
619         return _aligned;
620 }
621
622 FrameImage::FrameImage (AVFrame* frame)
623         : Image (static_cast<AVPixelFormat> (frame->format))
624         , _frame (frame)
625 {
626         _line_size = (int *) av_malloc (4 * sizeof (int));
627         _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
628         
629         for (int i = 0; i < components(); ++i) {
630                 _line_size[i] = size().width * bytes_per_pixel(i);
631         }
632 }
633
634 FrameImage::~FrameImage ()
635 {
636         av_frame_free (&_frame);
637         av_free (_line_size);
638 }
639
640 uint8_t **
641 FrameImage::data () const
642 {
643         return _frame->data;
644 }
645
646 int *
647 FrameImage::line_size () const
648 {
649         return _line_size;
650 }
651
652 int *
653 FrameImage::stride () const
654 {
655         /* AVFrame's `linesize' is what we call `stride' */
656         return _frame->linesize;
657 }
658
659 libdcp::Size
660 FrameImage::size () const
661 {
662         return libdcp::Size (_frame->width, _frame->height);
663 }
664
665 bool
666 FrameImage::aligned () const
667 {
668         return true;
669 }
670
671 RGBPlusAlphaImage::RGBPlusAlphaImage (shared_ptr<const Image> im)
672         : SimpleImage (im->pixel_format(), im->size(), false)
673 {
674         assert (im->pixel_format() == PIX_FMT_RGBA);
675
676         _alpha = (uint8_t *) av_malloc (im->size().width * im->size().height);
677
678         uint8_t* in = im->data()[0];
679         uint8_t* out = data()[0];
680         uint8_t* out_alpha = _alpha;
681         for (int y = 0; y < im->size().height; ++y) {
682                 uint8_t* in_r = in;
683                 for (int x = 0; x < im->size().width; ++x) {
684                         *out++ = *in_r++;
685                         *out++ = *in_r++;
686                         *out++ = *in_r++;
687                         *out_alpha++ = *in_r++;
688                 }
689
690                 in += im->stride()[0];
691         }
692 }
693
694 RGBPlusAlphaImage::~RGBPlusAlphaImage ()
695 {
696         av_free (_alpha);
697 }
698