Allow no-stretch scaling of video 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 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                 memset (data()[0], 0, lines(0) * stride()[0]);
302                 break;
303
304         case PIX_FMT_UYVY422:
305         {
306                 int const Y = lines(0);
307                 int const X = line_size()[0];
308                 uint8_t* p = data()[0];
309                 for (int y = 0; y < Y; ++y) {
310                         for (int x = 0; x < X / 4; ++x) {
311                                 *p++ = eight_bit_uv; // Cb
312                                 *p++ = 0;            // Y0
313                                 *p++ = eight_bit_uv; // Cr
314                                 *p++ = 0;            // Y1
315                         }
316                 }
317                 break;
318         }
319
320         default:
321                 throw PixelFormatError ("make_black()", _pixel_format);
322         }
323 }
324
325 void
326 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
327 {
328         /* Only implemented for RGBA onto RGB24 so far */
329         assert (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGBA);
330
331         int start_tx = position.x;
332         int start_ox = 0;
333
334         if (start_tx < 0) {
335                 start_ox = -start_tx;
336                 start_tx = 0;
337         }
338
339         int start_ty = position.y;
340         int start_oy = 0;
341
342         if (start_ty < 0) {
343                 start_oy = -start_ty;
344                 start_ty = 0;
345         }
346
347         for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
348                 uint8_t* tp = data()[0] + ty * stride()[0] + position.x * 3;
349                 uint8_t* op = other->data()[0] + oy * other->stride()[0];
350                 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
351                         float const alpha = float (op[3]) / 255;
352                         tp[0] = (tp[0] * (1 - alpha)) + op[0] * alpha;
353                         tp[1] = (tp[1] * (1 - alpha)) + op[1] * alpha;
354                         tp[2] = (tp[2] * (1 - alpha)) + op[2] * alpha;
355                         tp += 3;
356                         op += 4;
357                 }
358         }
359 }
360
361 void
362 Image::copy (shared_ptr<const Image> other, Position<int> position)
363 {
364         /* Only implemented for RGB24 onto RGB24 so far */
365         assert (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGB24);
366         assert (position.x >= 0 && position.y >= 0);
367
368         int const N = min (position.x + other->size().width, size().width) - position.x;
369         for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
370                 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
371                 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
372                 memcpy (tp, op, N * 3);
373         }
374 }       
375
376 void
377 Image::read_from_socket (shared_ptr<Socket> socket)
378 {
379         for (int i = 0; i < components(); ++i) {
380                 uint8_t* p = data()[i];
381                 for (int y = 0; y < lines(i); ++y) {
382                         socket->read (p, line_size()[i]);
383                         p += stride()[i];
384                 }
385         }
386 }
387
388 void
389 Image::write_to_socket (shared_ptr<Socket> socket) const
390 {
391         for (int i = 0; i < components(); ++i) {
392                 uint8_t* p = data()[i];
393                 for (int y = 0; y < lines(i); ++y) {
394                         socket->write (p, line_size()[i]);
395                         p += stride()[i];
396                 }
397         }
398 }
399
400
401 float
402 Image::bytes_per_pixel (int c) const
403 {
404         AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
405         if (!d) {
406                 throw PixelFormatError ("lines()", _pixel_format);
407         }
408
409         if (c >= components()) {
410                 return 0;
411         }
412
413         float bpp[4] = { 0, 0, 0, 0 };
414
415         bpp[0] = floor ((d->comp[0].depth_minus1 + 1 + 7) / 8);
416         if (d->nb_components > 1) {
417                 bpp[1] = floor ((d->comp[1].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
418         }
419         if (d->nb_components > 2) {
420                 bpp[2] = floor ((d->comp[2].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
421         }
422         if (d->nb_components > 3) {
423                 bpp[3] = floor ((d->comp[3].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
424         }
425         
426         if ((d->flags & PIX_FMT_PLANAR) == 0) {
427                 /* Not planar; sum them up */
428                 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
429         }
430
431         return bpp[c];
432 }
433
434 /** Construct a Image of a given size and format, allocating memory
435  *  as required.
436  *
437  *  @param p Pixel format.
438  *  @param s Size in pixels.
439  */
440 Image::Image (AVPixelFormat p, libdcp::Size s, bool aligned)
441         : libdcp::Image (s)
442         , _pixel_format (p)
443         , _aligned (aligned)
444 {
445         allocate ();
446 }
447
448 void
449 Image::allocate ()
450 {
451         _data = (uint8_t **) av_malloc (4 * sizeof (uint8_t *));
452         _data[0] = _data[1] = _data[2] = _data[3] = 0;
453         
454         _line_size = (int *) av_malloc (4 * sizeof (int));
455         _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
456         
457         _stride = (int *) av_malloc (4 * sizeof (int));
458         _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
459
460         for (int i = 0; i < components(); ++i) {
461                 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
462                 _stride[i] = stride_round_up (i, _line_size, _aligned ? 32 : 1);
463
464                 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
465                    uses a 16-byte fetch to read three bytes (R/G/B) of image data.
466                    Hence on the last pixel of the last line it reads over the end of
467                    the actual data by 1 byte.  If the width of an image is a multiple
468                    of the stride alignment there will be no padding at the end of image lines.
469                    OS X crashes on this illegal read, though other operating systems don't
470                    seem to mind.  The nasty + 1 in this malloc makes sure there is always a byte
471                    for that instruction to read safely.
472                 */
473                 _data[i] = (uint8_t *) av_malloc (_stride[i] * lines (i) + 1);
474         }
475 }
476
477 Image::Image (Image const & other)
478         : libdcp::Image (other)
479         ,  _pixel_format (other._pixel_format)
480         , _aligned (other._aligned)
481 {
482         allocate ();
483
484         for (int i = 0; i < components(); ++i) {
485                 uint8_t* p = _data[i];
486                 uint8_t* q = other._data[i];
487                 for (int j = 0; j < lines(i); ++j) {
488                         memcpy (p, q, _line_size[i]);
489                         p += stride()[i];
490                         q += other.stride()[i];
491                 }
492         }
493 }
494
495 Image::Image (AVFrame* frame)
496         : libdcp::Image (libdcp::Size (frame->width, frame->height))
497         , _pixel_format (static_cast<AVPixelFormat> (frame->format))
498         , _aligned (true)
499 {
500         allocate ();
501
502         for (int i = 0; i < components(); ++i) {
503                 uint8_t* p = _data[i];
504                 uint8_t* q = frame->data[i];
505                 for (int j = 0; j < lines(i); ++j) {
506                         memcpy (p, q, _line_size[i]);
507                         p += stride()[i];
508                         /* AVFrame's linesize is what we call `stride' */
509                         q += frame->linesize[i];
510                 }
511         }
512 }
513
514 Image::Image (shared_ptr<const Image> other, bool aligned)
515         : libdcp::Image (other)
516         , _pixel_format (other->_pixel_format)
517         , _aligned (aligned)
518 {
519         allocate ();
520
521         for (int i = 0; i < components(); ++i) {
522                 assert(line_size()[i] == other->line_size()[i]);
523                 uint8_t* p = _data[i];
524                 uint8_t* q = other->data()[i];
525                 for (int j = 0; j < lines(i); ++j) {
526                         memcpy (p, q, line_size()[i]);
527                         p += stride()[i];
528                         q += other->stride()[i];
529                 }
530         }
531 }
532
533 Image&
534 Image::operator= (Image const & other)
535 {
536         if (this == &other) {
537                 return *this;
538         }
539
540         Image tmp (other);
541         swap (tmp);
542         return *this;
543 }
544
545 void
546 Image::swap (Image & other)
547 {
548         libdcp::Image::swap (other);
549         
550         std::swap (_pixel_format, other._pixel_format);
551
552         for (int i = 0; i < 4; ++i) {
553                 std::swap (_data[i], other._data[i]);
554                 std::swap (_line_size[i], other._line_size[i]);
555                 std::swap (_stride[i], other._stride[i]);
556         }
557
558         std::swap (_aligned, other._aligned);
559 }
560
561 /** Destroy a Image */
562 Image::~Image ()
563 {
564         for (int i = 0; i < components(); ++i) {
565                 av_free (_data[i]);
566         }
567
568         av_free (_data);
569         av_free (_line_size);
570         av_free (_stride);
571 }
572
573 uint8_t **
574 Image::data () const
575 {
576         return _data;
577 }
578
579 int *
580 Image::line_size () const
581 {
582         return _line_size;
583 }
584
585 int *
586 Image::stride () const
587 {
588         return _stride;
589 }
590
591 libdcp::Size
592 Image::size () const
593 {
594         return _size;
595 }
596
597 bool
598 Image::aligned () const
599 {
600         return _aligned;
601 }
602