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 memset (data()[0], 0, lines(0) * stride()[0]);
272 memset (data()[1], eight_bit_uv, lines(1) * stride()[1]);
273 memset (data()[2], eight_bit_uv, lines(2) * stride()[2]);
276 case PIX_FMT_YUVJ420P:
277 case PIX_FMT_YUVJ422P:
278 case PIX_FMT_YUVJ444P:
279 memset (data()[0], 0, lines(0) * stride()[0]);
280 memset (data()[1], eight_bit_uv + 1, lines(1) * stride()[1]);
281 memset (data()[2], eight_bit_uv + 1, lines(2) * stride()[2]);
284 case PIX_FMT_YUV422P9LE:
285 case PIX_FMT_YUV444P9LE:
286 yuv_16_black (nine_bit_uv, false);
289 case PIX_FMT_YUV422P9BE:
290 case PIX_FMT_YUV444P9BE:
291 yuv_16_black (swap_16 (nine_bit_uv), false);
294 case PIX_FMT_YUV422P10LE:
295 case PIX_FMT_YUV444P10LE:
296 yuv_16_black (ten_bit_uv, false);
299 case PIX_FMT_YUV422P16LE:
300 case PIX_FMT_YUV444P16LE:
301 yuv_16_black (sixteen_bit_uv, false);
304 case PIX_FMT_YUV444P10BE:
305 case PIX_FMT_YUV422P10BE:
306 yuv_16_black (swap_16 (ten_bit_uv), false);
309 case AV_PIX_FMT_YUVA420P9BE:
310 case AV_PIX_FMT_YUVA422P9BE:
311 case AV_PIX_FMT_YUVA444P9BE:
312 yuv_16_black (swap_16 (nine_bit_uv), true);
315 case AV_PIX_FMT_YUVA420P9LE:
316 case AV_PIX_FMT_YUVA422P9LE:
317 case AV_PIX_FMT_YUVA444P9LE:
318 yuv_16_black (nine_bit_uv, true);
321 case AV_PIX_FMT_YUVA420P10BE:
322 case AV_PIX_FMT_YUVA422P10BE:
323 case AV_PIX_FMT_YUVA444P10BE:
324 yuv_16_black (swap_16 (ten_bit_uv), true);
327 case AV_PIX_FMT_YUVA420P10LE:
328 case AV_PIX_FMT_YUVA422P10LE:
329 case AV_PIX_FMT_YUVA444P10LE:
330 yuv_16_black (ten_bit_uv, true);
333 case AV_PIX_FMT_YUVA420P16BE:
334 case AV_PIX_FMT_YUVA422P16BE:
335 case AV_PIX_FMT_YUVA444P16BE:
336 yuv_16_black (swap_16 (sixteen_bit_uv), true);
339 case AV_PIX_FMT_YUVA420P16LE:
340 case AV_PIX_FMT_YUVA422P16LE:
341 case AV_PIX_FMT_YUVA444P16LE:
342 yuv_16_black (sixteen_bit_uv, true);
350 memset (data()[0], 0, lines(0) * stride()[0]);
353 case PIX_FMT_UYVY422:
355 int const Y = lines(0);
356 int const X = line_size()[0];
357 uint8_t* p = data()[0];
358 for (int y = 0; y < Y; ++y) {
359 for (int x = 0; x < X / 4; ++x) {
360 *p++ = eight_bit_uv; // Cb
362 *p++ = eight_bit_uv; // Cr
370 throw PixelFormatError ("make_black()", _pixel_format);
375 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
377 /* Only implemented for RGBA onto RGB24 so far */
378 assert (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGBA);
380 int start_tx = position.x;
384 start_ox = -start_tx;
388 int start_ty = position.y;
392 start_oy = -start_ty;
396 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
397 uint8_t* tp = data()[0] + ty * stride()[0] + position.x * 3;
398 uint8_t* op = other->data()[0] + oy * other->stride()[0];
399 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
400 float const alpha = float (op[3]) / 255;
401 tp[0] = (tp[0] * (1 - alpha)) + op[0] * alpha;
402 tp[1] = (tp[1] * (1 - alpha)) + op[1] * alpha;
403 tp[2] = (tp[2] * (1 - alpha)) + op[2] * alpha;
411 Image::copy (shared_ptr<const Image> other, Position<int> position)
413 /* Only implemented for RGB24 onto RGB24 so far */
414 assert (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGB24);
415 assert (position.x >= 0 && position.y >= 0);
417 int const N = min (position.x + other->size().width, size().width) - position.x;
418 for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
419 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
420 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
421 memcpy (tp, op, N * 3);
426 Image::read_from_socket (shared_ptr<Socket> socket)
428 for (int i = 0; i < components(); ++i) {
429 uint8_t* p = data()[i];
430 for (int y = 0; y < lines(i); ++y) {
431 socket->read (p, line_size()[i]);
438 Image::write_to_socket (shared_ptr<Socket> socket) const
440 for (int i = 0; i < components(); ++i) {
441 uint8_t* p = data()[i];
442 for (int y = 0; y < lines(i); ++y) {
443 socket->write (p, line_size()[i]);
451 Image::bytes_per_pixel (int c) const
453 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
455 throw PixelFormatError ("lines()", _pixel_format);
458 if (c >= components()) {
462 float bpp[4] = { 0, 0, 0, 0 };
464 bpp[0] = floor ((d->comp[0].depth_minus1 + 1 + 7) / 8);
465 if (d->nb_components > 1) {
466 bpp[1] = floor ((d->comp[1].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
468 if (d->nb_components > 2) {
469 bpp[2] = floor ((d->comp[2].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
471 if (d->nb_components > 3) {
472 bpp[3] = floor ((d->comp[3].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
475 if ((d->flags & PIX_FMT_PLANAR) == 0) {
476 /* Not planar; sum them up */
477 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
483 /** Construct a Image of a given size and format, allocating memory
486 * @param p Pixel format.
487 * @param s Size in pixels.
489 Image::Image (AVPixelFormat p, libdcp::Size s, bool aligned)
500 _data = (uint8_t **) av_malloc (4 * sizeof (uint8_t *));
501 _data[0] = _data[1] = _data[2] = _data[3] = 0;
503 _line_size = (int *) av_malloc (4 * sizeof (int));
504 _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
506 _stride = (int *) av_malloc (4 * sizeof (int));
507 _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
509 for (int i = 0; i < components(); ++i) {
510 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
511 _stride[i] = stride_round_up (i, _line_size, _aligned ? 32 : 1);
513 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
514 uses a 16-byte fetch to read three bytes (R/G/B) of image data.
515 Hence on the last pixel of the last line it reads over the end of
516 the actual data by 1 byte. If the width of an image is a multiple
517 of the stride alignment there will be no padding at the end of image lines.
518 OS X crashes on this illegal read, though other operating systems don't
519 seem to mind. The nasty + 1 in this malloc makes sure there is always a byte
520 for that instruction to read safely.
522 _data[i] = (uint8_t *) av_malloc (_stride[i] * lines (i) + 1);
526 Image::Image (Image const & other)
527 : libdcp::Image (other)
528 , _pixel_format (other._pixel_format)
529 , _aligned (other._aligned)
533 for (int i = 0; i < components(); ++i) {
534 uint8_t* p = _data[i];
535 uint8_t* q = other._data[i];
536 for (int j = 0; j < lines(i); ++j) {
537 memcpy (p, q, _line_size[i]);
539 q += other.stride()[i];
544 Image::Image (AVFrame* frame)
545 : libdcp::Image (libdcp::Size (frame->width, frame->height))
546 , _pixel_format (static_cast<AVPixelFormat> (frame->format))
551 for (int i = 0; i < components(); ++i) {
552 uint8_t* p = _data[i];
553 uint8_t* q = frame->data[i];
554 for (int j = 0; j < lines(i); ++j) {
555 memcpy (p, q, _line_size[i]);
557 /* AVFrame's linesize is what we call `stride' */
558 q += frame->linesize[i];
563 Image::Image (shared_ptr<const Image> other, bool aligned)
564 : libdcp::Image (other)
565 , _pixel_format (other->_pixel_format)
570 for (int i = 0; i < components(); ++i) {
571 assert(line_size()[i] == other->line_size()[i]);
572 uint8_t* p = _data[i];
573 uint8_t* q = other->data()[i];
574 for (int j = 0; j < lines(i); ++j) {
575 memcpy (p, q, line_size()[i]);
577 q += other->stride()[i];
583 Image::operator= (Image const & other)
585 if (this == &other) {
595 Image::swap (Image & other)
597 libdcp::Image::swap (other);
599 std::swap (_pixel_format, other._pixel_format);
601 for (int i = 0; i < 4; ++i) {
602 std::swap (_data[i], other._data[i]);
603 std::swap (_line_size[i], other._line_size[i]);
604 std::swap (_stride[i], other._stride[i]);
607 std::swap (_aligned, other._aligned);
610 /** Destroy a Image */
613 for (int i = 0; i < components(); ++i) {
618 av_free (_line_size);
629 Image::line_size () const
635 Image::stride () const
647 Image::aligned () const