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)
382 if (_pixel_format == PIX_FMT_BGRA && other->pixel_format() == PIX_FMT_RGBA) {
385 } else if (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGBA) {
392 int start_tx = position.x;
396 start_ox = -start_tx;
400 int start_ty = position.y;
404 start_oy = -start_ty;
408 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
409 uint8_t* tp = data()[0] + ty * stride()[0] + position.x * this_bpp;
410 uint8_t* op = other->data()[0] + oy * other->stride()[0];
411 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
412 float const alpha = float (op[3]) / 255;
413 tp[0] = (tp[0] * (1 - alpha)) + op[0] * alpha;
414 tp[1] = (tp[1] * (1 - alpha)) + op[1] * alpha;
415 tp[2] = (tp[2] * (1 - alpha)) + op[2] * alpha;
423 Image::copy (shared_ptr<const Image> other, Position<int> position)
425 /* Only implemented for RGB24 onto RGB24 so far */
426 assert (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGB24);
427 assert (position.x >= 0 && position.y >= 0);
429 int const N = min (position.x + other->size().width, size().width) - position.x;
430 for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
431 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
432 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
433 memcpy (tp, op, N * 3);
438 Image::read_from_socket (shared_ptr<Socket> socket)
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->read (p, line_size()[i]);
450 Image::write_to_socket (shared_ptr<Socket> socket) const
452 for (int i = 0; i < components(); ++i) {
453 uint8_t* p = data()[i];
454 for (int y = 0; y < lines(i); ++y) {
455 socket->write (p, line_size()[i]);
463 Image::bytes_per_pixel (int c) const
465 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
467 throw PixelFormatError ("lines()", _pixel_format);
470 if (c >= components()) {
474 float bpp[4] = { 0, 0, 0, 0 };
476 bpp[0] = floor ((d->comp[0].depth_minus1 + 1 + 7) / 8);
477 if (d->nb_components > 1) {
478 bpp[1] = floor ((d->comp[1].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
480 if (d->nb_components > 2) {
481 bpp[2] = floor ((d->comp[2].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
483 if (d->nb_components > 3) {
484 bpp[3] = floor ((d->comp[3].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
487 if ((d->flags & PIX_FMT_PLANAR) == 0) {
488 /* Not planar; sum them up */
489 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
495 /** Construct a Image of a given size and format, allocating memory
498 * @param p Pixel format.
499 * @param s Size in pixels.
501 Image::Image (AVPixelFormat p, libdcp::Size s, bool aligned)
512 _data = (uint8_t **) av_malloc (4 * sizeof (uint8_t *));
513 _data[0] = _data[1] = _data[2] = _data[3] = 0;
515 _line_size = (int *) av_malloc (4 * sizeof (int));
516 _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
518 _stride = (int *) av_malloc (4 * sizeof (int));
519 _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
521 for (int i = 0; i < components(); ++i) {
522 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
523 _stride[i] = stride_round_up (i, _line_size, _aligned ? 32 : 1);
525 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
526 uses a 16-byte fetch to read three bytes (R/G/B) of image data.
527 Hence on the last pixel of the last line it reads over the end of
528 the actual data by 1 byte. If the width of an image is a multiple
529 of the stride alignment there will be no padding at the end of image lines.
530 OS X crashes on this illegal read, though other operating systems don't
531 seem to mind. The nasty + 1 in this malloc makes sure there is always a byte
532 for that instruction to read safely.
534 _data[i] = (uint8_t *) av_malloc (_stride[i] * lines (i) + 1);
538 Image::Image (Image const & other)
539 : libdcp::Image (other)
540 , _pixel_format (other._pixel_format)
541 , _aligned (other._aligned)
545 for (int i = 0; i < components(); ++i) {
546 uint8_t* p = _data[i];
547 uint8_t* q = other._data[i];
548 for (int j = 0; j < lines(i); ++j) {
549 memcpy (p, q, _line_size[i]);
551 q += other.stride()[i];
556 Image::Image (AVFrame* frame)
557 : libdcp::Image (libdcp::Size (frame->width, frame->height))
558 , _pixel_format (static_cast<AVPixelFormat> (frame->format))
563 for (int i = 0; i < components(); ++i) {
564 uint8_t* p = _data[i];
565 uint8_t* q = frame->data[i];
566 for (int j = 0; j < lines(i); ++j) {
567 memcpy (p, q, _line_size[i]);
569 /* AVFrame's linesize is what we call `stride' */
570 q += frame->linesize[i];
575 Image::Image (shared_ptr<const Image> other, bool aligned)
576 : libdcp::Image (other)
577 , _pixel_format (other->_pixel_format)
582 for (int i = 0; i < components(); ++i) {
583 assert(line_size()[i] == other->line_size()[i]);
584 uint8_t* p = _data[i];
585 uint8_t* q = other->data()[i];
586 for (int j = 0; j < lines(i); ++j) {
587 memcpy (p, q, line_size()[i]);
589 q += other->stride()[i];
595 Image::operator= (Image const & other)
597 if (this == &other) {
607 Image::swap (Image & other)
609 libdcp::Image::swap (other);
611 std::swap (_pixel_format, other._pixel_format);
613 for (int i = 0; i < 4; ++i) {
614 std::swap (_data[i], other._data[i]);
615 std::swap (_line_size[i], other._line_size[i]);
616 std::swap (_stride[i], other._stride[i]);
619 std::swap (_aligned, other._aligned);
622 /** Destroy a Image */
625 for (int i = 0; i < components(); ++i) {
630 av_free (_line_size);
641 Image::line_size () const
647 Image::stride () const
659 Image::aligned () const