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"
38 using boost::shared_ptr;
42 Image::line_factor (int n) const
48 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
50 throw PixelFormatError ("lines()", _pixel_format);
53 return pow (2.0f, d->log2_chroma_h);
56 /** @param n Component index.
57 * @return Number of lines in the image for the given component.
60 Image::lines (int n) const
62 return rint (ceil (static_cast<double>(size().height) / line_factor (n)));
65 /** @return Number of components */
67 Image::components () const
69 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
71 throw PixelFormatError ("components()", _pixel_format);
74 if ((d->flags & PIX_FMT_PLANAR) == 0) {
78 return d->nb_components;
81 /** Crop this image, scale it to `inter_size' and then place it in a black frame of `out_size' */
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
86 /* Empirical testing suggests that sws_scale() will crash if
87 the input image is not aligned.
91 shared_ptr<Image> out (new Image (out_format, out_size, out_aligned));
94 libdcp::Size cropped_size = crop.apply (size ());
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
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));
107 Position<int> const corner ((out_size.width - inter_size.width) / 2, (out_size.height - inter_size.height) / 2);
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;
116 scale_in_data, stride(),
117 0, cropped_size.height,
118 scale_out_data, out->stride()
121 sws_freeContext (scale_context);
127 Image::scale (libdcp::Size out_size, Scaler const * scaler, AVPixelFormat out_format, bool out_aligned) const
130 /* Empirical testing suggests that sws_scale() will crash if
131 the input image is not aligned.
135 shared_ptr<Image> scaled (new Image (out_format, out_size, out_aligned));
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
147 scaled->data(), scaled->stride()
150 sws_freeContext (scale_context);
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.
160 Image::post_process (string pp, bool aligned) const
162 shared_ptr<Image> out (new Image (pixel_format(), size (), aligned));
165 switch (pixel_format()) {
166 case PIX_FMT_YUV420P:
167 pp_format = PP_FORMAT_420;
169 case PIX_FMT_YUV422P10LE:
170 case PIX_FMT_YUV422P:
171 case PIX_FMT_UYVY422:
172 pp_format = PP_FORMAT_422;
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;
181 throw PixelFormatError ("post_process", pixel_format());
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);
188 (const uint8_t **) data(), stride(),
189 out->data(), out->stride(),
190 size().width, size().height,
191 0, 0, mode, context, 0
195 pp_free_context (context);
201 Image::crop (Crop crop, bool aligned) const
203 libdcp::Size cropped_size = crop.apply (size ());
204 shared_ptr<Image> out (new Image (pixel_format(), cropped_size, aligned));
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.
212 int const cropped_width_in_bytes = ceil (bytes_per_pixel(c) * cropped_size.width);
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];
218 for (int y = 0; y < out->lines(c); ++y) {
219 memcpy (out_p, in_p + crop_left_in_bytes, cropped_width_in_bytes);
221 out_p += out->stride()[c];
228 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
230 Image::yuv_16_black (uint16_t v, bool alpha)
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) {
240 p += stride()[i] / 2;
245 memset (data()[3], 0, lines(3) * stride()[3]);
250 Image::swap_16 (uint16_t v)
252 return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
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;
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]);
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]);
285 case PIX_FMT_YUV422P9LE:
286 case PIX_FMT_YUV444P9LE:
287 yuv_16_black (nine_bit_uv, false);
290 case PIX_FMT_YUV422P9BE:
291 case PIX_FMT_YUV444P9BE:
292 yuv_16_black (swap_16 (nine_bit_uv), false);
295 case PIX_FMT_YUV422P10LE:
296 case PIX_FMT_YUV444P10LE:
297 yuv_16_black (ten_bit_uv, false);
300 case PIX_FMT_YUV422P16LE:
301 case PIX_FMT_YUV444P16LE:
302 yuv_16_black (sixteen_bit_uv, false);
305 case PIX_FMT_YUV444P10BE:
306 case PIX_FMT_YUV422P10BE:
307 yuv_16_black (swap_16 (ten_bit_uv), false);
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);
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);
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);
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);
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);
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);
351 memset (data()[0], 0, lines(0) * stride()[0]);
354 case PIX_FMT_UYVY422:
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
363 *p++ = eight_bit_uv; // Cr
371 throw PixelFormatError ("make_black()", _pixel_format);
376 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
378 /* Only implemented for RGBA onto RGB24 so far */
379 assert (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGBA);
381 int start_tx = position.x;
385 start_ox = -start_tx;
389 int start_ty = position.y;
393 start_oy = -start_ty;
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;
412 Image::copy (shared_ptr<const Image> other, Position<int> position)
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);
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);
427 Image::read_from_socket (shared_ptr<Socket> socket)
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]);
439 Image::write_to_socket (shared_ptr<Socket> socket) const
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]);
452 Image::bytes_per_pixel (int c) const
454 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
456 throw PixelFormatError ("lines()", _pixel_format);
459 if (c >= components()) {
463 float bpp[4] = { 0, 0, 0, 0 };
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);
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);
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);
476 if ((d->flags & PIX_FMT_PLANAR) == 0) {
477 /* Not planar; sum them up */
478 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
484 /** Construct a Image of a given size and format, allocating memory
487 * @param p Pixel format.
488 * @param s Size in pixels.
490 Image::Image (AVPixelFormat p, libdcp::Size s, bool aligned)
501 _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
502 _data[0] = _data[1] = _data[2] = _data[3] = 0;
504 _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
505 _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
507 _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
508 _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
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);
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.
523 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * lines (i) + 1);
527 Image::Image (Image const & other)
528 : libdcp::Image (other)
529 , _pixel_format (other._pixel_format)
530 , _aligned (other._aligned)
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]);
540 q += other.stride()[i];
545 Image::Image (AVFrame* frame)
546 : libdcp::Image (libdcp::Size (frame->width, frame->height))
547 , _pixel_format (static_cast<AVPixelFormat> (frame->format))
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]);
558 /* AVFrame's linesize is what we call `stride' */
559 q += frame->linesize[i];
564 Image::Image (shared_ptr<const Image> other, bool aligned)
565 : libdcp::Image (other)
566 , _pixel_format (other->_pixel_format)
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]);
578 q += other->stride()[i];
584 Image::operator= (Image const & other)
586 if (this == &other) {
596 Image::swap (Image & other)
598 libdcp::Image::swap (other);
600 std::swap (_pixel_format, other._pixel_format);
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]);
608 std::swap (_aligned, other._aligned);
611 /** Destroy a Image */
614 for (int i = 0; i < components(); ++i) {
619 av_free (_line_size);
630 Image::line_size () const
636 Image::stride () const
648 Image::aligned () const