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>
29 #include <libpostproc/postprocess.h>
32 #include "exceptions.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);
170 /** Run a FFmpeg post-process on this image and return the processed version.
171 * @param pp Flags for the required set of post processes.
172 * @return Post-processed image.
175 Image::post_process (string pp, bool aligned) const
177 shared_ptr<Image> out (new Image (pixel_format(), size (), aligned));
180 switch (pixel_format()) {
181 case PIX_FMT_YUV420P:
182 pp_format = PP_FORMAT_420;
184 case PIX_FMT_YUV422P10LE:
185 case PIX_FMT_YUV422P:
186 case PIX_FMT_UYVY422:
187 pp_format = PP_FORMAT_422;
189 case PIX_FMT_YUV444P:
190 case PIX_FMT_YUV444P9BE:
191 case PIX_FMT_YUV444P9LE:
192 case PIX_FMT_YUV444P10BE:
193 case PIX_FMT_YUV444P10LE:
194 pp_format = PP_FORMAT_444;
196 throw PixelFormatError ("post_process", pixel_format());
199 pp_mode* mode = pp_get_mode_by_name_and_quality (pp.c_str (), PP_QUALITY_MAX);
200 pp_context* context = pp_get_context (size().width, size().height, pp_format | PP_CPU_CAPS_MMX2);
203 (const uint8_t **) data(), stride(),
204 out->data(), out->stride(),
205 size().width, size().height,
206 0, 0, mode, context, 0
210 pp_free_context (context);
216 Image::crop (Crop crop, bool aligned) const
218 libdcp::Size cropped_size = crop.apply (size ());
219 shared_ptr<Image> out (new Image (pixel_format(), cropped_size, aligned));
221 for (int c = 0; c < components(); ++c) {
222 int const crop_left_in_bytes = bytes_per_pixel(c) * crop.left;
223 /* bytes_per_pixel() could be a fraction; in this case the stride will be rounded
224 up, and we need to make sure that we copy over the width (up to the stride)
225 rather than short of the width; hence the ceil() here.
227 int const cropped_width_in_bytes = ceil (bytes_per_pixel(c) * cropped_size.width);
229 /* Start of the source line, cropped from the top but not the left */
230 uint8_t* in_p = data()[c] + (crop.top / out->line_factor(c)) * stride()[c];
231 uint8_t* out_p = out->data()[c];
233 for (int y = 0; y < out->lines(c); ++y) {
234 memcpy (out_p, in_p + crop_left_in_bytes, cropped_width_in_bytes);
236 out_p += out->stride()[c];
243 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
245 Image::yuv_16_black (uint16_t v, bool alpha)
247 memset (data()[0], 0, lines(0) * stride()[0]);
248 for (int i = 1; i < 3; ++i) {
249 int16_t* p = reinterpret_cast<int16_t*> (data()[i]);
250 for (int y = 0; y < lines(i); ++y) {
251 /* We divide by 2 here because we are writing 2 bytes at a time */
252 for (int x = 0; x < line_size()[i] / 2; ++x) {
255 p += stride()[i] / 2;
260 memset (data()[3], 0, lines(3) * stride()[3]);
265 Image::swap_16 (uint16_t v)
267 return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
273 /* U/V black value for 8-bit colour */
274 static uint8_t const eight_bit_uv = (1 << 7) - 1;
275 /* U/V black value for 9-bit colour */
276 static uint16_t const nine_bit_uv = (1 << 8) - 1;
277 /* U/V black value for 10-bit colour */
278 static uint16_t const ten_bit_uv = (1 << 9) - 1;
279 /* U/V black value for 16-bit colour */
280 static uint16_t const sixteen_bit_uv = (1 << 15) - 1;
282 switch (_pixel_format) {
283 case PIX_FMT_YUV420P:
284 case PIX_FMT_YUV422P:
285 case PIX_FMT_YUV444P:
286 case PIX_FMT_YUV411P:
287 memset (data()[0], 0, lines(0) * stride()[0]);
288 memset (data()[1], eight_bit_uv, lines(1) * stride()[1]);
289 memset (data()[2], eight_bit_uv, lines(2) * stride()[2]);
292 case PIX_FMT_YUVJ420P:
293 case PIX_FMT_YUVJ422P:
294 case PIX_FMT_YUVJ444P:
295 memset (data()[0], 0, lines(0) * stride()[0]);
296 memset (data()[1], eight_bit_uv + 1, lines(1) * stride()[1]);
297 memset (data()[2], eight_bit_uv + 1, lines(2) * stride()[2]);
300 case PIX_FMT_YUV422P9LE:
301 case PIX_FMT_YUV444P9LE:
302 yuv_16_black (nine_bit_uv, false);
305 case PIX_FMT_YUV422P9BE:
306 case PIX_FMT_YUV444P9BE:
307 yuv_16_black (swap_16 (nine_bit_uv), false);
310 case PIX_FMT_YUV422P10LE:
311 case PIX_FMT_YUV444P10LE:
312 yuv_16_black (ten_bit_uv, false);
315 case PIX_FMT_YUV422P16LE:
316 case PIX_FMT_YUV444P16LE:
317 yuv_16_black (sixteen_bit_uv, false);
320 case PIX_FMT_YUV444P10BE:
321 case PIX_FMT_YUV422P10BE:
322 yuv_16_black (swap_16 (ten_bit_uv), false);
325 case AV_PIX_FMT_YUVA420P9BE:
326 case AV_PIX_FMT_YUVA422P9BE:
327 case AV_PIX_FMT_YUVA444P9BE:
328 yuv_16_black (swap_16 (nine_bit_uv), true);
331 case AV_PIX_FMT_YUVA420P9LE:
332 case AV_PIX_FMT_YUVA422P9LE:
333 case AV_PIX_FMT_YUVA444P9LE:
334 yuv_16_black (nine_bit_uv, true);
337 case AV_PIX_FMT_YUVA420P10BE:
338 case AV_PIX_FMT_YUVA422P10BE:
339 case AV_PIX_FMT_YUVA444P10BE:
340 yuv_16_black (swap_16 (ten_bit_uv), true);
343 case AV_PIX_FMT_YUVA420P10LE:
344 case AV_PIX_FMT_YUVA422P10LE:
345 case AV_PIX_FMT_YUVA444P10LE:
346 yuv_16_black (ten_bit_uv, true);
349 case AV_PIX_FMT_YUVA420P16BE:
350 case AV_PIX_FMT_YUVA422P16BE:
351 case AV_PIX_FMT_YUVA444P16BE:
352 yuv_16_black (swap_16 (sixteen_bit_uv), true);
355 case AV_PIX_FMT_YUVA420P16LE:
356 case AV_PIX_FMT_YUVA422P16LE:
357 case AV_PIX_FMT_YUVA444P16LE:
358 yuv_16_black (sixteen_bit_uv, true);
366 memset (data()[0], 0, lines(0) * stride()[0]);
369 case PIX_FMT_UYVY422:
371 int const Y = lines(0);
372 int const X = line_size()[0];
373 uint8_t* p = data()[0];
374 for (int y = 0; y < Y; ++y) {
375 for (int x = 0; x < X / 4; ++x) {
376 *p++ = eight_bit_uv; // Cb
378 *p++ = eight_bit_uv; // Cr
386 throw PixelFormatError ("make_black()", _pixel_format);
391 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
393 /* Only implemented for RGBA onto RGB24 so far */
394 assert (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGBA);
396 int start_tx = position.x;
400 start_ox = -start_tx;
404 int start_ty = position.y;
408 start_oy = -start_ty;
412 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
413 uint8_t* tp = data()[0] + ty * stride()[0] + position.x * 3;
414 uint8_t* op = other->data()[0] + oy * other->stride()[0];
415 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
416 float const alpha = float (op[3]) / 255;
417 tp[0] = (tp[0] * (1 - alpha)) + op[0] * alpha;
418 tp[1] = (tp[1] * (1 - alpha)) + op[1] * alpha;
419 tp[2] = (tp[2] * (1 - alpha)) + op[2] * alpha;
427 Image::copy (shared_ptr<const Image> other, Position<int> position)
429 /* Only implemented for RGB24 onto RGB24 so far */
430 assert (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGB24);
431 assert (position.x >= 0 && position.y >= 0);
433 int const N = min (position.x + other->size().width, size().width) - position.x;
434 for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
435 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
436 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
437 memcpy (tp, op, N * 3);
442 Image::read_from_socket (shared_ptr<Socket> socket)
444 for (int i = 0; i < components(); ++i) {
445 uint8_t* p = data()[i];
446 for (int y = 0; y < lines(i); ++y) {
447 socket->read (p, line_size()[i]);
454 Image::write_to_socket (shared_ptr<Socket> socket) const
456 for (int i = 0; i < components(); ++i) {
457 uint8_t* p = data()[i];
458 for (int y = 0; y < lines(i); ++y) {
459 socket->write (p, line_size()[i]);
467 Image::bytes_per_pixel (int c) const
469 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
471 throw PixelFormatError ("lines()", _pixel_format);
474 if (c >= components()) {
478 float bpp[4] = { 0, 0, 0, 0 };
480 bpp[0] = floor ((d->comp[0].depth_minus1 + 1 + 7) / 8);
481 if (d->nb_components > 1) {
482 bpp[1] = floor ((d->comp[1].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
484 if (d->nb_components > 2) {
485 bpp[2] = floor ((d->comp[2].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
487 if (d->nb_components > 3) {
488 bpp[3] = floor ((d->comp[3].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
491 if ((d->flags & PIX_FMT_PLANAR) == 0) {
492 /* Not planar; sum them up */
493 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
499 /** Construct a Image of a given size and format, allocating memory
502 * @param p Pixel format.
503 * @param s Size in pixels.
505 Image::Image (AVPixelFormat p, libdcp::Size s, bool aligned)
516 _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
517 _data[0] = _data[1] = _data[2] = _data[3] = 0;
519 _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
520 _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
522 _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
523 _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
525 for (int i = 0; i < components(); ++i) {
526 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
527 _stride[i] = stride_round_up (i, _line_size, _aligned ? 32 : 1);
529 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
530 uses a 16-byte fetch to read three bytes (R/G/B) of image data.
531 Hence on the last pixel of the last line it reads over the end of
532 the actual data by 1 byte. If the width of an image is a multiple
533 of the stride alignment there will be no padding at the end of image lines.
534 OS X crashes on this illegal read, though other operating systems don't
535 seem to mind. The nasty + 1 in this malloc makes sure there is always a byte
536 for that instruction to read safely.
538 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * lines (i) + 1);
542 Image::Image (Image const & other)
543 : libdcp::Image (other)
544 , _pixel_format (other._pixel_format)
545 , _aligned (other._aligned)
549 for (int i = 0; i < components(); ++i) {
550 uint8_t* p = _data[i];
551 uint8_t* q = other._data[i];
552 for (int j = 0; j < lines(i); ++j) {
553 memcpy (p, q, _line_size[i]);
555 q += other.stride()[i];
560 Image::Image (AVFrame* frame)
561 : libdcp::Image (libdcp::Size (frame->width, frame->height))
562 , _pixel_format (static_cast<AVPixelFormat> (frame->format))
567 for (int i = 0; i < components(); ++i) {
568 uint8_t* p = _data[i];
569 uint8_t* q = frame->data[i];
570 for (int j = 0; j < lines(i); ++j) {
571 memcpy (p, q, _line_size[i]);
573 /* AVFrame's linesize is what we call `stride' */
574 q += frame->linesize[i];
579 Image::Image (shared_ptr<const Image> other, bool aligned)
580 : libdcp::Image (other)
581 , _pixel_format (other->_pixel_format)
586 for (int i = 0; i < components(); ++i) {
587 assert(line_size()[i] == other->line_size()[i]);
588 uint8_t* p = _data[i];
589 uint8_t* q = other->data()[i];
590 for (int j = 0; j < lines(i); ++j) {
591 memcpy (p, q, line_size()[i]);
593 q += other->stride()[i];
599 Image::operator= (Image const & other)
601 if (this == &other) {
611 Image::swap (Image & other)
613 libdcp::Image::swap (other);
615 std::swap (_pixel_format, other._pixel_format);
617 for (int i = 0; i < 4; ++i) {
618 std::swap (_data[i], other._data[i]);
619 std::swap (_line_size[i], other._line_size[i]);
620 std::swap (_stride[i], other._stride[i]);
623 std::swap (_aligned, other._aligned);
626 /** Destroy a Image */
629 for (int i = 0; i < components(); ++i) {
634 av_free (_line_size);
645 Image::line_size () const
651 Image::stride () const
663 Image::aligned () const