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