2 Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
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.
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.
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.
20 /** @file src/image.cc
21 * @brief A class to describe a video image.
26 #include <libswscale/swscale.h>
27 #include <libavutil/pixfmt.h>
28 #include <libavutil/pixdesc.h>
31 #include "exceptions.h"
33 #include "md5_digester.h"
41 using boost::shared_ptr;
45 Image::line_factor (int n) const
51 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
53 throw PixelFormatError ("lines()", _pixel_format);
56 return pow (2.0f, d->log2_chroma_h);
59 /** @param n Component index.
60 * @return Number of lines in the image for the given component.
63 Image::lines (int n) const
65 return rint (ceil (static_cast<double>(size().height) / line_factor (n)));
68 /** @return Number of components */
70 Image::components () const
72 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
74 throw PixelFormatError ("components()", _pixel_format);
77 if ((d->flags & PIX_FMT_PLANAR) == 0) {
81 return d->nb_components;
84 /** Crop this image, scale it to `inter_size' and then place it in a black frame of `out_size' */
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
89 /* Empirical testing suggests that sws_scale() will crash if
90 the input image is not aligned.
94 assert (out_size.width >= inter_size.width);
95 assert (out_size.height >= inter_size.height);
97 /* Here's an image of out_size */
98 shared_ptr<Image> out (new Image (out_format, out_size, out_aligned));
101 /* Size of the image after any crop */
102 libdcp::Size const cropped_size = crop.apply (size ());
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
111 if (!scale_context) {
112 throw StringError (N_("Could not allocate SwsContext"));
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));
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);
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;
131 scale_in_data, stride(),
132 0, cropped_size.height,
133 scale_out_data, out->stride()
136 sws_freeContext (scale_context);
142 Image::scale (libdcp::Size out_size, Scaler const * scaler, AVPixelFormat out_format, bool out_aligned) const
145 /* Empirical testing suggests that sws_scale() will crash if
146 the input image is not aligned.
150 shared_ptr<Image> scaled (new Image (out_format, out_size, out_aligned));
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
162 scaled->data(), scaled->stride()
165 sws_freeContext (scale_context);
171 Image::crop (Crop crop, bool aligned) const
173 libdcp::Size cropped_size = crop.apply (size ());
174 shared_ptr<Image> out (new Image (pixel_format(), cropped_size, aligned));
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.
182 int const cropped_width_in_bytes = ceil (bytes_per_pixel(c) * cropped_size.width);
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];
188 for (int y = 0; y < out->lines(c); ++y) {
189 memcpy (out_p, in_p + crop_left_in_bytes, cropped_width_in_bytes);
191 out_p += out->stride()[c];
198 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
200 Image::yuv_16_black (uint16_t v, bool alpha)
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) {
210 p += stride()[i] / 2;
215 memset (data()[3], 0, lines(3) * stride()[3]);
220 Image::swap_16 (uint16_t v)
222 return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
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;
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]);
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]);
255 case PIX_FMT_YUV422P9LE:
256 case PIX_FMT_YUV444P9LE:
257 yuv_16_black (nine_bit_uv, false);
260 case PIX_FMT_YUV422P9BE:
261 case PIX_FMT_YUV444P9BE:
262 yuv_16_black (swap_16 (nine_bit_uv), false);
265 case PIX_FMT_YUV422P10LE:
266 case PIX_FMT_YUV444P10LE:
267 yuv_16_black (ten_bit_uv, false);
270 case PIX_FMT_YUV422P16LE:
271 case PIX_FMT_YUV444P16LE:
272 yuv_16_black (sixteen_bit_uv, false);
275 case PIX_FMT_YUV444P10BE:
276 case PIX_FMT_YUV422P10BE:
277 yuv_16_black (swap_16 (ten_bit_uv), false);
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);
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);
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);
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);
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);
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);
321 case PIX_FMT_RGB555LE:
322 case PIX_FMT_RGB48LE:
323 case PIX_FMT_RGB48BE:
324 memset (data()[0], 0, lines(0) * stride()[0]);
327 case PIX_FMT_UYVY422:
329 int const Y = lines(0);
330 int const X = line_size()[0];
331 uint8_t* p = data()[0];
332 for (int y = 0; y < Y; ++y) {
333 for (int x = 0; x < X / 4; ++x) {
334 *p++ = eight_bit_uv; // Cb
336 *p++ = eight_bit_uv; // Cr
344 throw PixelFormatError ("make_black()", _pixel_format);
349 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
351 /* Only implemented for RGBA onto RGB24 so far */
352 assert (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGBA);
354 int start_tx = position.x;
358 start_ox = -start_tx;
362 int start_ty = position.y;
366 start_oy = -start_ty;
370 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
371 uint8_t* tp = data()[0] + ty * stride()[0] + position.x * 3;
372 uint8_t* op = other->data()[0] + oy * other->stride()[0];
373 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
374 float const alpha = float (op[3]) / 255;
375 tp[0] = (tp[0] * (1 - alpha)) + op[0] * alpha;
376 tp[1] = (tp[1] * (1 - alpha)) + op[1] * alpha;
377 tp[2] = (tp[2] * (1 - alpha)) + op[2] * alpha;
385 Image::copy (shared_ptr<const Image> other, Position<int> position)
387 /* Only implemented for RGB24 onto RGB24 so far */
388 assert (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGB24);
389 assert (position.x >= 0 && position.y >= 0);
391 int const N = min (position.x + other->size().width, size().width) - position.x;
392 for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
393 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
394 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
395 memcpy (tp, op, N * 3);
400 Image::read_from_socket (shared_ptr<Socket> socket)
402 for (int i = 0; i < components(); ++i) {
403 uint8_t* p = data()[i];
404 for (int y = 0; y < lines(i); ++y) {
405 socket->read (p, line_size()[i]);
412 Image::write_to_socket (shared_ptr<Socket> socket) const
414 for (int i = 0; i < components(); ++i) {
415 uint8_t* p = data()[i];
416 for (int y = 0; y < lines(i); ++y) {
417 socket->write (p, line_size()[i]);
425 Image::bytes_per_pixel (int c) const
427 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
429 throw PixelFormatError ("lines()", _pixel_format);
432 if (c >= components()) {
436 float bpp[4] = { 0, 0, 0, 0 };
438 bpp[0] = floor ((d->comp[0].depth_minus1 + 1 + 7) / 8);
439 if (d->nb_components > 1) {
440 bpp[1] = floor ((d->comp[1].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
442 if (d->nb_components > 2) {
443 bpp[2] = floor ((d->comp[2].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
445 if (d->nb_components > 3) {
446 bpp[3] = floor ((d->comp[3].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
449 if ((d->flags & PIX_FMT_PLANAR) == 0) {
450 /* Not planar; sum them up */
451 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
457 /** Construct a Image of a given size and format, allocating memory
460 * @param p Pixel format.
461 * @param s Size in pixels.
463 Image::Image (AVPixelFormat p, libdcp::Size s, bool aligned)
474 _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
475 _data[0] = _data[1] = _data[2] = _data[3] = 0;
477 _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
478 _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
480 _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
481 _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
483 for (int i = 0; i < components(); ++i) {
484 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
485 _stride[i] = stride_round_up (i, _line_size, _aligned ? 32 : 1);
487 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
488 uses a 16-byte fetch to read three bytes (R/G/B) of image data.
489 Hence on the last pixel of the last line it reads over the end of
490 the actual data by 1 byte. If the width of an image is a multiple
491 of the stride alignment there will be no padding at the end of image lines.
492 OS X crashes on this illegal read, though other operating systems don't
493 seem to mind. The nasty + 1 in this malloc makes sure there is always a byte
494 for that instruction to read safely.
496 Further to the above, valgrind is now telling me that ff_rgb24ToY_ssse3
497 over-reads by more then _avx. I can't follow the code to work out how much,
498 so I'll just over-allocate by 32 bytes and have done with it. Empirical
499 testing suggests that it works.
501 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * lines (i) + 32);
505 Image::Image (Image const & other)
506 : libdcp::Image (other)
507 , _pixel_format (other._pixel_format)
508 , _aligned (other._aligned)
512 for (int i = 0; i < components(); ++i) {
513 uint8_t* p = _data[i];
514 uint8_t* q = other._data[i];
515 for (int j = 0; j < lines(i); ++j) {
516 memcpy (p, q, _line_size[i]);
518 q += other.stride()[i];
523 Image::Image (AVFrame* frame)
524 : libdcp::Image (libdcp::Size (frame->width, frame->height))
525 , _pixel_format (static_cast<AVPixelFormat> (frame->format))
530 for (int i = 0; i < components(); ++i) {
531 uint8_t* p = _data[i];
532 uint8_t* q = frame->data[i];
533 for (int j = 0; j < lines(i); ++j) {
534 memcpy (p, q, _line_size[i]);
536 /* AVFrame's linesize is what we call `stride' */
537 q += frame->linesize[i];
542 Image::Image (shared_ptr<const Image> other, bool aligned)
543 : libdcp::Image (other)
544 , _pixel_format (other->_pixel_format)
549 for (int i = 0; i < components(); ++i) {
550 assert(line_size()[i] == other->line_size()[i]);
551 uint8_t* p = _data[i];
552 uint8_t* q = other->data()[i];
553 for (int j = 0; j < lines(i); ++j) {
554 memcpy (p, q, line_size()[i]);
556 q += other->stride()[i];
562 Image::operator= (Image const & other)
564 if (this == &other) {
574 Image::swap (Image & other)
576 libdcp::Image::swap (other);
578 std::swap (_pixel_format, other._pixel_format);
580 for (int i = 0; i < 4; ++i) {
581 std::swap (_data[i], other._data[i]);
582 std::swap (_line_size[i], other._line_size[i]);
583 std::swap (_stride[i], other._stride[i]);
586 std::swap (_aligned, other._aligned);
589 /** Destroy a Image */
592 for (int i = 0; i < components(); ++i) {
597 av_free (_line_size);
608 Image::line_size () const
614 Image::stride () const
626 Image::aligned () const
632 Image::digest () const
634 MD5Digester digester;
636 for (int i = 0; i < components(); ++i) {
637 digester.add (data()[i], line_size()[i]);
640 return digester.get ();