2 Copyright (C) 2012-2014 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"
42 using boost::shared_ptr;
46 Image::line_factor (int n) const
52 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
54 throw PixelFormatError ("lines()", _pixel_format);
57 return pow (2.0f, d->log2_chroma_h);
60 /** @param n Component index.
61 * @return Number of lines in the image for the given component.
64 Image::lines (int n) const
66 return rint (ceil (static_cast<double>(size().height) / line_factor (n)));
69 /** @return Number of components */
71 Image::components () const
73 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
75 throw PixelFormatError ("components()", _pixel_format);
78 if ((d->flags & PIX_FMT_PLANAR) == 0) {
82 return d->nb_components;
85 /** Crop this image, scale it to `inter_size' and then place it in a black frame of `out_size' */
87 Image::crop_scale_window (Crop crop, dcp::Size inter_size, dcp::Size out_size, Scaler const * scaler, AVPixelFormat out_format, bool out_aligned) const
90 /* Empirical testing suggests that sws_scale() will crash if
91 the input image is not aligned.
95 assert (out_size.width >= inter_size.width);
96 assert (out_size.height >= inter_size.height);
98 /* Here's an image of out_size */
99 shared_ptr<Image> out (new Image (out_format, out_size, out_aligned));
102 /* Size of the image after any crop */
103 dcp::Size const cropped_size = crop.apply (size ());
105 /* Scale context for a scale from cropped_size to inter_size */
106 struct SwsContext* scale_context = sws_getContext (
107 cropped_size.width, cropped_size.height, pixel_format(),
108 inter_size.width, inter_size.height, out_format,
109 scaler->ffmpeg_id (), 0, 0, 0
112 if (!scale_context) {
113 throw StringError (N_("Could not allocate SwsContext"));
116 /* Prepare input data pointers with crop */
117 uint8_t* scale_in_data[components()];
118 for (int c = 0; c < components(); ++c) {
119 scale_in_data[c] = data()[c] + int (rint (bytes_per_pixel(c) * crop.left)) + stride()[c] * (crop.top / line_factor(c));
122 /* Corner of the image within out_size */
123 Position<int> const corner ((out_size.width - inter_size.width) / 2, (out_size.height - inter_size.height) / 2);
125 uint8_t* scale_out_data[out->components()];
126 for (int c = 0; c < out->components(); ++c) {
127 scale_out_data[c] = out->data()[c] + int (rint (out->bytes_per_pixel(c) * corner.x)) + out->stride()[c] * corner.y;
132 scale_in_data, stride(),
133 0, cropped_size.height,
134 scale_out_data, out->stride()
137 sws_freeContext (scale_context);
143 Image::scale (dcp::Size out_size, Scaler const * scaler, AVPixelFormat out_format, bool out_aligned) const
146 /* Empirical testing suggests that sws_scale() will crash if
147 the input image is not aligned.
151 shared_ptr<Image> scaled (new Image (out_format, out_size, out_aligned));
153 struct SwsContext* scale_context = sws_getContext (
154 size().width, size().height, pixel_format(),
155 out_size.width, out_size.height, out_format,
156 scaler->ffmpeg_id (), 0, 0, 0
163 scaled->data(), scaled->stride()
166 sws_freeContext (scale_context);
171 /** Run a FFmpeg post-process on this image and return the processed version.
172 * @param pp Flags for the required set of post processes.
173 * @return Post-processed image.
176 Image::post_process (string pp, bool aligned) const
178 shared_ptr<Image> out (new Image (pixel_format(), size (), aligned));
181 switch (pixel_format()) {
182 case PIX_FMT_YUV420P:
183 pp_format = PP_FORMAT_420;
185 case PIX_FMT_YUV422P10LE:
186 case PIX_FMT_YUV422P:
187 case PIX_FMT_UYVY422:
188 pp_format = PP_FORMAT_422;
190 case PIX_FMT_YUV444P:
191 case PIX_FMT_YUV444P9BE:
192 case PIX_FMT_YUV444P9LE:
193 case PIX_FMT_YUV444P10BE:
194 case PIX_FMT_YUV444P10LE:
195 pp_format = PP_FORMAT_444;
197 throw PixelFormatError ("post_process", pixel_format());
200 pp_mode* mode = pp_get_mode_by_name_and_quality (pp.c_str (), PP_QUALITY_MAX);
201 pp_context* context = pp_get_context (size().width, size().height, pp_format | PP_CPU_CAPS_MMX2);
204 (const uint8_t **) data(), stride(),
205 out->data(), out->stride(),
206 size().width, size().height,
207 0, 0, mode, context, 0
211 pp_free_context (context);
217 Image::crop (Crop crop, bool aligned) const
219 dcp::Size cropped_size = crop.apply (size ());
220 shared_ptr<Image> out (new Image (pixel_format(), cropped_size, aligned));
222 for (int c = 0; c < components(); ++c) {
223 int const crop_left_in_bytes = bytes_per_pixel(c) * crop.left;
224 /* bytes_per_pixel() could be a fraction; in this case the stride will be rounded
225 up, and we need to make sure that we copy over the width (up to the stride)
226 rather than short of the width; hence the ceil() here.
228 int const cropped_width_in_bytes = ceil (bytes_per_pixel(c) * cropped_size.width);
230 /* Start of the source line, cropped from the top but not the left */
231 uint8_t* in_p = data()[c] + (crop.top / out->line_factor(c)) * stride()[c];
232 uint8_t* out_p = out->data()[c];
234 for (int y = 0; y < out->lines(c); ++y) {
235 memcpy (out_p, in_p + crop_left_in_bytes, cropped_width_in_bytes);
237 out_p += out->stride()[c];
244 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
246 Image::yuv_16_black (uint16_t v, bool alpha)
248 memset (data()[0], 0, lines(0) * stride()[0]);
249 for (int i = 1; i < 3; ++i) {
250 int16_t* p = reinterpret_cast<int16_t*> (data()[i]);
251 for (int y = 0; y < lines(i); ++y) {
252 /* We divide by 2 here because we are writing 2 bytes at a time */
253 for (int x = 0; x < line_size()[i] / 2; ++x) {
256 p += stride()[i] / 2;
261 memset (data()[3], 0, lines(3) * stride()[3]);
266 Image::swap_16 (uint16_t v)
268 return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
274 /* U/V black value for 8-bit colour */
275 static uint8_t const eight_bit_uv = (1 << 7) - 1;
276 /* U/V black value for 9-bit colour */
277 static uint16_t const nine_bit_uv = (1 << 8) - 1;
278 /* U/V black value for 10-bit colour */
279 static uint16_t const ten_bit_uv = (1 << 9) - 1;
280 /* U/V black value for 16-bit colour */
281 static uint16_t const sixteen_bit_uv = (1 << 15) - 1;
283 switch (_pixel_format) {
284 case PIX_FMT_YUV420P:
285 case PIX_FMT_YUV422P:
286 case PIX_FMT_YUV444P:
287 case PIX_FMT_YUV411P:
288 memset (data()[0], 0, lines(0) * stride()[0]);
289 memset (data()[1], eight_bit_uv, lines(1) * stride()[1]);
290 memset (data()[2], eight_bit_uv, lines(2) * stride()[2]);
293 case PIX_FMT_YUVJ420P:
294 case PIX_FMT_YUVJ422P:
295 case PIX_FMT_YUVJ444P:
296 memset (data()[0], 0, lines(0) * stride()[0]);
297 memset (data()[1], eight_bit_uv + 1, lines(1) * stride()[1]);
298 memset (data()[2], eight_bit_uv + 1, lines(2) * stride()[2]);
301 case PIX_FMT_YUV422P9LE:
302 case PIX_FMT_YUV444P9LE:
303 yuv_16_black (nine_bit_uv, false);
306 case PIX_FMT_YUV422P9BE:
307 case PIX_FMT_YUV444P9BE:
308 yuv_16_black (swap_16 (nine_bit_uv), false);
311 case PIX_FMT_YUV422P10LE:
312 case PIX_FMT_YUV444P10LE:
313 yuv_16_black (ten_bit_uv, false);
316 case PIX_FMT_YUV422P16LE:
317 case PIX_FMT_YUV444P16LE:
318 yuv_16_black (sixteen_bit_uv, false);
321 case PIX_FMT_YUV444P10BE:
322 case PIX_FMT_YUV422P10BE:
323 yuv_16_black (swap_16 (ten_bit_uv), false);
326 case AV_PIX_FMT_YUVA420P9BE:
327 case AV_PIX_FMT_YUVA422P9BE:
328 case AV_PIX_FMT_YUVA444P9BE:
329 yuv_16_black (swap_16 (nine_bit_uv), true);
332 case AV_PIX_FMT_YUVA420P9LE:
333 case AV_PIX_FMT_YUVA422P9LE:
334 case AV_PIX_FMT_YUVA444P9LE:
335 yuv_16_black (nine_bit_uv, true);
338 case AV_PIX_FMT_YUVA420P10BE:
339 case AV_PIX_FMT_YUVA422P10BE:
340 case AV_PIX_FMT_YUVA444P10BE:
341 yuv_16_black (swap_16 (ten_bit_uv), true);
344 case AV_PIX_FMT_YUVA420P10LE:
345 case AV_PIX_FMT_YUVA422P10LE:
346 case AV_PIX_FMT_YUVA444P10LE:
347 yuv_16_black (ten_bit_uv, true);
350 case AV_PIX_FMT_YUVA420P16BE:
351 case AV_PIX_FMT_YUVA422P16BE:
352 case AV_PIX_FMT_YUVA444P16BE:
353 yuv_16_black (swap_16 (sixteen_bit_uv), true);
356 case AV_PIX_FMT_YUVA420P16LE:
357 case AV_PIX_FMT_YUVA422P16LE:
358 case AV_PIX_FMT_YUVA444P16LE:
359 yuv_16_black (sixteen_bit_uv, true);
367 memset (data()[0], 0, lines(0) * stride()[0]);
370 case PIX_FMT_UYVY422:
372 int const Y = lines(0);
373 int const X = line_size()[0];
374 uint8_t* p = data()[0];
375 for (int y = 0; y < Y; ++y) {
376 for (int x = 0; x < X / 4; ++x) {
377 *p++ = eight_bit_uv; // Cb
379 *p++ = eight_bit_uv; // Cr
387 throw PixelFormatError ("make_black()", _pixel_format);
392 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
397 if (_pixel_format == PIX_FMT_BGRA && other->pixel_format() == PIX_FMT_RGBA) {
400 } else if (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGBA) {
407 int start_tx = position.x;
411 start_ox = -start_tx;
415 int start_ty = position.y;
419 start_oy = -start_ty;
423 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
424 uint8_t* tp = data()[0] + ty * stride()[0] + position.x * this_bpp;
425 uint8_t* op = other->data()[0] + oy * other->stride()[0];
426 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
427 float const alpha = float (op[3]) / 255;
428 tp[0] = (tp[0] * (1 - alpha)) + op[0] * alpha;
429 tp[1] = (tp[1] * (1 - alpha)) + op[1] * alpha;
430 tp[2] = (tp[2] * (1 - alpha)) + op[2] * alpha;
438 Image::copy (shared_ptr<const Image> other, Position<int> position)
440 /* Only implemented for RGB24 onto RGB24 so far */
441 assert (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGB24);
442 assert (position.x >= 0 && position.y >= 0);
444 int const N = min (position.x + other->size().width, size().width) - position.x;
445 for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
446 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
447 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
448 memcpy (tp, op, N * 3);
453 Image::read_from_socket (shared_ptr<Socket> socket)
455 for (int i = 0; i < components(); ++i) {
456 uint8_t* p = data()[i];
457 for (int y = 0; y < lines(i); ++y) {
458 socket->read (p, line_size()[i]);
465 Image::write_to_socket (shared_ptr<Socket> socket) const
467 for (int i = 0; i < components(); ++i) {
468 uint8_t* p = data()[i];
469 for (int y = 0; y < lines(i); ++y) {
470 socket->write (p, line_size()[i]);
478 Image::bytes_per_pixel (int c) const
480 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
482 throw PixelFormatError ("lines()", _pixel_format);
485 if (c >= components()) {
489 float bpp[4] = { 0, 0, 0, 0 };
491 bpp[0] = floor ((d->comp[0].depth_minus1 + 1 + 7) / 8);
492 if (d->nb_components > 1) {
493 bpp[1] = floor ((d->comp[1].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
495 if (d->nb_components > 2) {
496 bpp[2] = floor ((d->comp[2].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
498 if (d->nb_components > 3) {
499 bpp[3] = floor ((d->comp[3].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
502 if ((d->flags & PIX_FMT_PLANAR) == 0) {
503 /* Not planar; sum them up */
504 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
510 /** Construct a Image of a given size and format, allocating memory
513 * @param p Pixel format.
514 * @param s Size in pixels.
516 Image::Image (AVPixelFormat p, dcp::Size s, bool aligned)
527 _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
528 _data[0] = _data[1] = _data[2] = _data[3] = 0;
530 _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
531 _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
533 _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
534 _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
536 for (int i = 0; i < components(); ++i) {
537 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
538 _stride[i] = stride_round_up (i, _line_size, _aligned ? 32 : 1);
540 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
541 uses a 16-byte fetch to read three bytes (R/G/B) of image data.
542 Hence on the last pixel of the last line it reads over the end of
543 the actual data by 1 byte. If the width of an image is a multiple
544 of the stride alignment there will be no padding at the end of image lines.
545 OS X crashes on this illegal read, though other operating systems don't
546 seem to mind. The nasty + 1 in this malloc makes sure there is always a byte
547 for that instruction to read safely.
549 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * lines (i) + 1);
553 Image::Image (Image const & other)
555 , _pixel_format (other._pixel_format)
556 , _aligned (other._aligned)
560 for (int i = 0; i < components(); ++i) {
561 uint8_t* p = _data[i];
562 uint8_t* q = other._data[i];
563 for (int j = 0; j < lines(i); ++j) {
564 memcpy (p, q, _line_size[i]);
566 q += other.stride()[i];
571 Image::Image (AVFrame* frame)
572 : dcp::Image (dcp::Size (frame->width, frame->height))
573 , _pixel_format (static_cast<AVPixelFormat> (frame->format))
578 for (int i = 0; i < components(); ++i) {
579 uint8_t* p = _data[i];
580 uint8_t* q = frame->data[i];
581 for (int j = 0; j < lines(i); ++j) {
582 memcpy (p, q, _line_size[i]);
584 /* AVFrame's linesize is what we call `stride' */
585 q += frame->linesize[i];
590 Image::Image (shared_ptr<const Image> other, bool aligned)
592 , _pixel_format (other->_pixel_format)
597 for (int i = 0; i < components(); ++i) {
598 assert(line_size()[i] == other->line_size()[i]);
599 uint8_t* p = _data[i];
600 uint8_t* q = other->data()[i];
601 for (int j = 0; j < lines(i); ++j) {
602 memcpy (p, q, line_size()[i]);
604 q += other->stride()[i];
610 Image::operator= (Image const & other)
612 if (this == &other) {
622 Image::swap (Image & other)
624 dcp::Image::swap (other);
626 std::swap (_pixel_format, other._pixel_format);
628 for (int i = 0; i < 4; ++i) {
629 std::swap (_data[i], other._data[i]);
630 std::swap (_line_size[i], other._line_size[i]);
631 std::swap (_stride[i], other._stride[i]);
634 std::swap (_aligned, other._aligned);
637 /** Destroy a Image */
640 for (int i = 0; i < components(); ++i) {
645 av_free (_line_size);
656 Image::line_size () const
662 Image::stride () const
674 Image::aligned () const