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