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