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"
39 using boost::shared_ptr;
43 Image::line_factor (int n) const
49 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
51 throw PixelFormatError ("lines()", _pixel_format);
54 return pow (2.0f, d->log2_chroma_h);
57 /** @param n Component index.
58 * @return Number of lines in the image for the given component.
61 Image::lines (int n) const
63 return rint (ceil (static_cast<double>(size().height) / line_factor (n)));
66 /** @return Number of components */
68 Image::components () const
70 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
72 throw PixelFormatError ("components()", _pixel_format);
75 if ((d->flags & PIX_FMT_PLANAR) == 0) {
79 return d->nb_components;
82 /** Crop this image, scale it to `inter_size' and then place it in a black frame of `out_size' */
84 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 /* Empirical testing suggests that sws_scale() will crash if
88 the input image is not aligned.
92 shared_ptr<Image> out (new Image (out_format, out_size, out_aligned));
95 libdcp::Size cropped_size = crop.apply (size ());
97 struct SwsContext* scale_context = sws_getContext (
98 cropped_size.width, cropped_size.height, pixel_format(),
99 inter_size.width, inter_size.height, out_format,
100 scaler->ffmpeg_id (), 0, 0, 0
103 uint8_t* scale_in_data[components()];
104 for (int c = 0; c < components(); ++c) {
105 scale_in_data[c] = data()[c] + int (rint (bytes_per_pixel(c) * crop.left)) + stride()[c] * (crop.top / line_factor(c));
108 Position<int> const corner ((out_size.width - inter_size.width) / 2, (out_size.height - inter_size.height) / 2);
110 uint8_t* scale_out_data[components()];
111 for (int c = 0; c < components(); ++c) {
112 scale_out_data[c] = out->data()[c] + int (rint (out->bytes_per_pixel(c) * corner.x)) + out->stride()[c] * corner.y;
117 scale_in_data, stride(),
118 0, cropped_size.height,
119 scale_out_data, out->stride()
122 sws_freeContext (scale_context);
128 Image::scale (libdcp::Size out_size, Scaler const * scaler, AVPixelFormat out_format, bool out_aligned) const
131 /* Empirical testing suggests that sws_scale() will crash if
132 the input image is not aligned.
136 shared_ptr<Image> scaled (new Image (out_format, out_size, out_aligned));
138 struct SwsContext* scale_context = sws_getContext (
139 size().width, size().height, pixel_format(),
140 out_size.width, out_size.height, out_format,
141 scaler->ffmpeg_id (), 0, 0, 0
148 scaled->data(), scaled->stride()
151 sws_freeContext (scale_context);
156 /** Run a FFmpeg post-process on this image and return the processed version.
157 * @param pp Flags for the required set of post processes.
158 * @return Post-processed image.
161 Image::post_process (string pp, bool aligned) const
163 shared_ptr<Image> out (new Image (pixel_format(), size (), aligned));
166 switch (pixel_format()) {
167 case PIX_FMT_YUV420P:
168 pp_format = PP_FORMAT_420;
170 case PIX_FMT_YUV422P10LE:
171 case PIX_FMT_YUV422P:
172 case PIX_FMT_UYVY422:
173 pp_format = PP_FORMAT_422;
175 case PIX_FMT_YUV444P:
176 case PIX_FMT_YUV444P9BE:
177 case PIX_FMT_YUV444P9LE:
178 case PIX_FMT_YUV444P10BE:
179 case PIX_FMT_YUV444P10LE:
180 pp_format = PP_FORMAT_444;
182 throw PixelFormatError ("post_process", pixel_format());
185 pp_mode* mode = pp_get_mode_by_name_and_quality (pp.c_str (), PP_QUALITY_MAX);
186 pp_context* context = pp_get_context (size().width, size().height, pp_format | PP_CPU_CAPS_MMX2);
189 (const uint8_t **) data(), stride(),
190 out->data(), out->stride(),
191 size().width, size().height,
192 0, 0, mode, context, 0
196 pp_free_context (context);
202 Image::crop (Crop crop, bool aligned) const
204 libdcp::Size cropped_size = crop.apply (size ());
205 shared_ptr<Image> out (new Image (pixel_format(), cropped_size, aligned));
207 for (int c = 0; c < components(); ++c) {
208 int const crop_left_in_bytes = bytes_per_pixel(c) * crop.left;
209 /* bytes_per_pixel() could be a fraction; in this case the stride will be rounded
210 up, and we need to make sure that we copy over the width (up to the stride)
211 rather than short of the width; hence the ceil() here.
213 int const cropped_width_in_bytes = ceil (bytes_per_pixel(c) * cropped_size.width);
215 /* Start of the source line, cropped from the top but not the left */
216 uint8_t* in_p = data()[c] + (crop.top / out->line_factor(c)) * stride()[c];
217 uint8_t* out_p = out->data()[c];
219 for (int y = 0; y < out->lines(c); ++y) {
220 memcpy (out_p, in_p + crop_left_in_bytes, cropped_width_in_bytes);
222 out_p += out->stride()[c];
229 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
231 Image::yuv_16_black (uint16_t v, bool alpha)
233 memset (data()[0], 0, lines(0) * stride()[0]);
234 for (int i = 1; i < 3; ++i) {
235 int16_t* p = reinterpret_cast<int16_t*> (data()[i]);
236 for (int y = 0; y < lines(i); ++y) {
237 /* We divide by 2 here because we are writing 2 bytes at a time */
238 for (int x = 0; x < line_size()[i] / 2; ++x) {
241 p += stride()[i] / 2;
246 memset (data()[3], 0, lines(3) * stride()[3]);
251 Image::swap_16 (uint16_t v)
253 return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
259 /* U/V black value for 8-bit colour */
260 static uint8_t const eight_bit_uv = (1 << 7) - 1;
261 /* U/V black value for 9-bit colour */
262 static uint16_t const nine_bit_uv = (1 << 8) - 1;
263 /* U/V black value for 10-bit colour */
264 static uint16_t const ten_bit_uv = (1 << 9) - 1;
265 /* U/V black value for 16-bit colour */
266 static uint16_t const sixteen_bit_uv = (1 << 15) - 1;
268 switch (_pixel_format) {
269 case PIX_FMT_YUV420P:
270 case PIX_FMT_YUV422P:
271 case PIX_FMT_YUV444P:
272 case PIX_FMT_YUV411P:
273 memset (data()[0], 0, lines(0) * stride()[0]);
274 memset (data()[1], eight_bit_uv, lines(1) * stride()[1]);
275 memset (data()[2], eight_bit_uv, lines(2) * stride()[2]);
278 case PIX_FMT_YUVJ420P:
279 case PIX_FMT_YUVJ422P:
280 case PIX_FMT_YUVJ444P:
281 memset (data()[0], 0, lines(0) * stride()[0]);
282 memset (data()[1], eight_bit_uv + 1, lines(1) * stride()[1]);
283 memset (data()[2], eight_bit_uv + 1, lines(2) * stride()[2]);
286 case PIX_FMT_YUV422P9LE:
287 case PIX_FMT_YUV444P9LE:
288 yuv_16_black (nine_bit_uv, false);
291 case PIX_FMT_YUV422P9BE:
292 case PIX_FMT_YUV444P9BE:
293 yuv_16_black (swap_16 (nine_bit_uv), false);
296 case PIX_FMT_YUV422P10LE:
297 case PIX_FMT_YUV444P10LE:
298 yuv_16_black (ten_bit_uv, false);
301 case PIX_FMT_YUV422P16LE:
302 case PIX_FMT_YUV444P16LE:
303 yuv_16_black (sixteen_bit_uv, false);
306 case PIX_FMT_YUV444P10BE:
307 case PIX_FMT_YUV422P10BE:
308 yuv_16_black (swap_16 (ten_bit_uv), false);
311 case AV_PIX_FMT_YUVA420P9BE:
312 case AV_PIX_FMT_YUVA422P9BE:
313 case AV_PIX_FMT_YUVA444P9BE:
314 yuv_16_black (swap_16 (nine_bit_uv), true);
317 case AV_PIX_FMT_YUVA420P9LE:
318 case AV_PIX_FMT_YUVA422P9LE:
319 case AV_PIX_FMT_YUVA444P9LE:
320 yuv_16_black (nine_bit_uv, true);
323 case AV_PIX_FMT_YUVA420P10BE:
324 case AV_PIX_FMT_YUVA422P10BE:
325 case AV_PIX_FMT_YUVA444P10BE:
326 yuv_16_black (swap_16 (ten_bit_uv), true);
329 case AV_PIX_FMT_YUVA420P10LE:
330 case AV_PIX_FMT_YUVA422P10LE:
331 case AV_PIX_FMT_YUVA444P10LE:
332 yuv_16_black (ten_bit_uv, true);
335 case AV_PIX_FMT_YUVA420P16BE:
336 case AV_PIX_FMT_YUVA422P16BE:
337 case AV_PIX_FMT_YUVA444P16BE:
338 yuv_16_black (swap_16 (sixteen_bit_uv), true);
341 case AV_PIX_FMT_YUVA420P16LE:
342 case AV_PIX_FMT_YUVA422P16LE:
343 case AV_PIX_FMT_YUVA444P16LE:
344 yuv_16_black (sixteen_bit_uv, true);
352 memset (data()[0], 0, lines(0) * stride()[0]);
355 case PIX_FMT_UYVY422:
357 int const Y = lines(0);
358 int const X = line_size()[0];
359 uint8_t* p = data()[0];
360 for (int y = 0; y < Y; ++y) {
361 for (int x = 0; x < X / 4; ++x) {
362 *p++ = eight_bit_uv; // Cb
364 *p++ = eight_bit_uv; // Cr
372 throw PixelFormatError ("make_black()", _pixel_format);
377 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
379 /* Only implemented for RGBA onto BGRA so far */
380 assert (_pixel_format == PIX_FMT_BGRA && other->pixel_format() == PIX_FMT_RGBA);
382 int const this_bpp = 4;
383 int const other_bpp = 4;
385 int start_tx = position.x;
389 start_ox = -start_tx;
393 int start_ty = position.y;
397 start_oy = -start_ty;
401 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
402 uint8_t* tp = data()[0] + ty * stride()[0] + position.x * this_bpp;
403 uint8_t* op = other->data()[0] + oy * other->stride()[0];
404 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
405 float const alpha = float (op[3]) / 255;
406 tp[0] = (tp[0] * (1 - alpha)) + op[0] * alpha;
407 tp[1] = (tp[1] * (1 - alpha)) + op[1] * alpha;
408 tp[2] = (tp[2] * (1 - alpha)) + op[2] * alpha;
416 Image::copy (shared_ptr<const Image> other, Position<int> position)
418 /* Only implemented for RGB24 onto RGB24 so far */
419 assert (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGB24);
420 assert (position.x >= 0 && position.y >= 0);
422 int const N = min (position.x + other->size().width, size().width) - position.x;
423 for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
424 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
425 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
426 memcpy (tp, op, N * 3);
431 Image::read_from_socket (shared_ptr<Socket> socket)
433 for (int i = 0; i < components(); ++i) {
434 uint8_t* p = data()[i];
435 for (int y = 0; y < lines(i); ++y) {
436 socket->read (p, line_size()[i]);
443 Image::write_to_socket (shared_ptr<Socket> socket) const
445 for (int i = 0; i < components(); ++i) {
446 uint8_t* p = data()[i];
447 for (int y = 0; y < lines(i); ++y) {
448 socket->write (p, line_size()[i]);
456 Image::bytes_per_pixel (int c) const
458 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
460 throw PixelFormatError ("lines()", _pixel_format);
463 if (c >= components()) {
467 float bpp[4] = { 0, 0, 0, 0 };
469 bpp[0] = floor ((d->comp[0].depth_minus1 + 1 + 7) / 8);
470 if (d->nb_components > 1) {
471 bpp[1] = floor ((d->comp[1].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
473 if (d->nb_components > 2) {
474 bpp[2] = floor ((d->comp[2].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
476 if (d->nb_components > 3) {
477 bpp[3] = floor ((d->comp[3].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
480 if ((d->flags & PIX_FMT_PLANAR) == 0) {
481 /* Not planar; sum them up */
482 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
488 /** Construct a Image of a given size and format, allocating memory
491 * @param p Pixel format.
492 * @param s Size in pixels.
494 Image::Image (AVPixelFormat p, libdcp::Size s, bool aligned)
505 _data = (uint8_t **) av_malloc (4 * sizeof (uint8_t *));
506 _data[0] = _data[1] = _data[2] = _data[3] = 0;
508 _line_size = (int *) av_malloc (4 * sizeof (int));
509 _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
511 _stride = (int *) av_malloc (4 * sizeof (int));
512 _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
514 for (int i = 0; i < components(); ++i) {
515 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
516 _stride[i] = stride_round_up (i, _line_size, _aligned ? 32 : 1);
518 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
519 uses a 16-byte fetch to read three bytes (R/G/B) of image data.
520 Hence on the last pixel of the last line it reads over the end of
521 the actual data by 1 byte. If the width of an image is a multiple
522 of the stride alignment there will be no padding at the end of image lines.
523 OS X crashes on this illegal read, though other operating systems don't
524 seem to mind. The nasty + 1 in this malloc makes sure there is always a byte
525 for that instruction to read safely.
527 _data[i] = (uint8_t *) av_malloc (_stride[i] * lines (i) + 1);
531 Image::Image (Image const & other)
532 : libdcp::Image (other)
533 , _pixel_format (other._pixel_format)
534 , _aligned (other._aligned)
538 for (int i = 0; i < components(); ++i) {
539 uint8_t* p = _data[i];
540 uint8_t* q = other._data[i];
541 for (int j = 0; j < lines(i); ++j) {
542 memcpy (p, q, _line_size[i]);
544 q += other.stride()[i];
549 Image::Image (AVFrame* frame)
550 : libdcp::Image (libdcp::Size (frame->width, frame->height))
551 , _pixel_format (static_cast<AVPixelFormat> (frame->format))
556 for (int i = 0; i < components(); ++i) {
557 uint8_t* p = _data[i];
558 uint8_t* q = frame->data[i];
559 for (int j = 0; j < lines(i); ++j) {
560 memcpy (p, q, _line_size[i]);
562 /* AVFrame's linesize is what we call `stride' */
563 q += frame->linesize[i];
568 Image::Image (shared_ptr<const Image> other, bool aligned)
569 : libdcp::Image (other)
570 , _pixel_format (other->_pixel_format)
575 for (int i = 0; i < components(); ++i) {
576 assert(line_size()[i] == other->line_size()[i]);
577 uint8_t* p = _data[i];
578 uint8_t* q = other->data()[i];
579 for (int j = 0; j < lines(i); ++j) {
580 memcpy (p, q, line_size()[i]);
582 q += other->stride()[i];
588 Image::operator= (Image const & other)
590 if (this == &other) {
600 Image::swap (Image & other)
602 libdcp::Image::swap (other);
604 std::swap (_pixel_format, other._pixel_format);
606 for (int i = 0; i < 4; ++i) {
607 std::swap (_data[i], other._data[i]);
608 std::swap (_line_size[i], other._line_size[i]);
609 std::swap (_stride[i], other._stride[i]);
612 std::swap (_aligned, other._aligned);
615 /** Destroy a Image */
618 for (int i = 0; i < components(); ++i) {
623 av_free (_line_size);
634 Image::line_size () const
640 Image::stride () const
652 Image::aligned () const