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>
31 #include "exceptions.h"
40 using boost::shared_ptr;
44 Image::line_factor (int n) const
50 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
52 throw PixelFormatError ("lines()", _pixel_format);
55 return pow (2.0f, d->log2_chroma_h);
58 /** @param n Component index.
59 * @return Number of lines in the image for the given component.
62 Image::lines (int n) const
64 return rint (ceil (static_cast<double>(size().height) / line_factor (n)));
67 /** @return Number of components */
69 Image::components () const
71 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
73 throw PixelFormatError ("components()", _pixel_format);
76 if ((d->flags & PIX_FMT_PLANAR) == 0) {
80 return d->nb_components;
83 /** Crop this image, scale it to `inter_size' and then place it in a black frame of `out_size' */
85 Image::crop_scale_window (Crop crop, libdcp::Size inter_size, libdcp::Size out_size, Scaler const * scaler, AVPixelFormat out_format, bool out_aligned) const
88 /* Empirical testing suggests that sws_scale() will crash if
89 the input image is not aligned.
93 assert (out_size.width >= inter_size.width);
94 assert (out_size.height >= inter_size.height);
96 /* Here's an image of out_size */
97 shared_ptr<Image> out (new Image (out_format, out_size, out_aligned));
100 /* Size of the image after any crop */
101 libdcp::Size const cropped_size = crop.apply (size ());
103 /* Scale context for a scale from cropped_size to inter_size */
104 struct SwsContext* scale_context = sws_getContext (
105 cropped_size.width, cropped_size.height, pixel_format(),
106 inter_size.width, inter_size.height, out_format,
107 scaler->ffmpeg_id (), 0, 0, 0
110 if (!scale_context) {
111 throw StringError (N_("Could not allocate SwsContext"));
114 /* Prepare input data pointers with crop */
115 uint8_t* scale_in_data[components()];
116 for (int c = 0; c < components(); ++c) {
117 scale_in_data[c] = data()[c] + int (rint (bytes_per_pixel(c) * crop.left)) + stride()[c] * (crop.top / line_factor(c));
120 /* Corner of the image within out_size */
121 Position<int> const corner ((out_size.width - inter_size.width) / 2, (out_size.height - inter_size.height) / 2);
123 uint8_t* scale_out_data[out->components()];
124 for (int c = 0; c < out->components(); ++c) {
125 scale_out_data[c] = out->data()[c] + int (rint (out->bytes_per_pixel(c) * corner.x)) + out->stride()[c] * corner.y;
130 scale_in_data, stride(),
131 0, cropped_size.height,
132 scale_out_data, out->stride()
135 sws_freeContext (scale_context);
141 Image::scale (libdcp::Size out_size, Scaler const * scaler, AVPixelFormat out_format, bool out_aligned) const
144 /* Empirical testing suggests that sws_scale() will crash if
145 the input image is not aligned.
149 shared_ptr<Image> scaled (new Image (out_format, out_size, out_aligned));
151 struct SwsContext* scale_context = sws_getContext (
152 size().width, size().height, pixel_format(),
153 out_size.width, out_size.height, out_format,
154 scaler->ffmpeg_id (), 0, 0, 0
161 scaled->data(), scaled->stride()
164 sws_freeContext (scale_context);
170 Image::crop (Crop crop, bool aligned) const
172 libdcp::Size cropped_size = crop.apply (size ());
173 shared_ptr<Image> out (new Image (pixel_format(), cropped_size, aligned));
175 for (int c = 0; c < components(); ++c) {
176 int const crop_left_in_bytes = bytes_per_pixel(c) * crop.left;
177 /* bytes_per_pixel() could be a fraction; in this case the stride will be rounded
178 up, and we need to make sure that we copy over the width (up to the stride)
179 rather than short of the width; hence the ceil() here.
181 int const cropped_width_in_bytes = ceil (bytes_per_pixel(c) * cropped_size.width);
183 /* Start of the source line, cropped from the top but not the left */
184 uint8_t* in_p = data()[c] + (crop.top / out->line_factor(c)) * stride()[c];
185 uint8_t* out_p = out->data()[c];
187 for (int y = 0; y < out->lines(c); ++y) {
188 memcpy (out_p, in_p + crop_left_in_bytes, cropped_width_in_bytes);
190 out_p += out->stride()[c];
197 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
199 Image::yuv_16_black (uint16_t v, bool alpha)
201 memset (data()[0], 0, lines(0) * stride()[0]);
202 for (int i = 1; i < 3; ++i) {
203 int16_t* p = reinterpret_cast<int16_t*> (data()[i]);
204 for (int y = 0; y < lines(i); ++y) {
205 /* We divide by 2 here because we are writing 2 bytes at a time */
206 for (int x = 0; x < line_size()[i] / 2; ++x) {
209 p += stride()[i] / 2;
214 memset (data()[3], 0, lines(3) * stride()[3]);
219 Image::swap_16 (uint16_t v)
221 return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
227 /* U/V black value for 8-bit colour */
228 static uint8_t const eight_bit_uv = (1 << 7) - 1;
229 /* U/V black value for 9-bit colour */
230 static uint16_t const nine_bit_uv = (1 << 8) - 1;
231 /* U/V black value for 10-bit colour */
232 static uint16_t const ten_bit_uv = (1 << 9) - 1;
233 /* U/V black value for 16-bit colour */
234 static uint16_t const sixteen_bit_uv = (1 << 15) - 1;
236 switch (_pixel_format) {
237 case PIX_FMT_YUV420P:
238 case PIX_FMT_YUV422P:
239 case PIX_FMT_YUV444P:
240 case PIX_FMT_YUV411P:
241 memset (data()[0], 0, lines(0) * stride()[0]);
242 memset (data()[1], eight_bit_uv, lines(1) * stride()[1]);
243 memset (data()[2], eight_bit_uv, lines(2) * stride()[2]);
246 case PIX_FMT_YUVJ420P:
247 case PIX_FMT_YUVJ422P:
248 case PIX_FMT_YUVJ444P:
249 memset (data()[0], 0, lines(0) * stride()[0]);
250 memset (data()[1], eight_bit_uv + 1, lines(1) * stride()[1]);
251 memset (data()[2], eight_bit_uv + 1, lines(2) * stride()[2]);
254 case PIX_FMT_YUV422P9LE:
255 case PIX_FMT_YUV444P9LE:
256 yuv_16_black (nine_bit_uv, false);
259 case PIX_FMT_YUV422P9BE:
260 case PIX_FMT_YUV444P9BE:
261 yuv_16_black (swap_16 (nine_bit_uv), false);
264 case PIX_FMT_YUV422P10LE:
265 case PIX_FMT_YUV444P10LE:
266 yuv_16_black (ten_bit_uv, false);
269 case PIX_FMT_YUV422P16LE:
270 case PIX_FMT_YUV444P16LE:
271 yuv_16_black (sixteen_bit_uv, false);
274 case PIX_FMT_YUV444P10BE:
275 case PIX_FMT_YUV422P10BE:
276 yuv_16_black (swap_16 (ten_bit_uv), false);
279 case AV_PIX_FMT_YUVA420P9BE:
280 case AV_PIX_FMT_YUVA422P9BE:
281 case AV_PIX_FMT_YUVA444P9BE:
282 yuv_16_black (swap_16 (nine_bit_uv), true);
285 case AV_PIX_FMT_YUVA420P9LE:
286 case AV_PIX_FMT_YUVA422P9LE:
287 case AV_PIX_FMT_YUVA444P9LE:
288 yuv_16_black (nine_bit_uv, true);
291 case AV_PIX_FMT_YUVA420P10BE:
292 case AV_PIX_FMT_YUVA422P10BE:
293 case AV_PIX_FMT_YUVA444P10BE:
294 yuv_16_black (swap_16 (ten_bit_uv), true);
297 case AV_PIX_FMT_YUVA420P10LE:
298 case AV_PIX_FMT_YUVA422P10LE:
299 case AV_PIX_FMT_YUVA444P10LE:
300 yuv_16_black (ten_bit_uv, true);
303 case AV_PIX_FMT_YUVA420P16BE:
304 case AV_PIX_FMT_YUVA422P16BE:
305 case AV_PIX_FMT_YUVA444P16BE:
306 yuv_16_black (swap_16 (sixteen_bit_uv), true);
309 case AV_PIX_FMT_YUVA420P16LE:
310 case AV_PIX_FMT_YUVA422P16LE:
311 case AV_PIX_FMT_YUVA444P16LE:
312 yuv_16_black (sixteen_bit_uv, true);
320 memset (data()[0], 0, lines(0) * stride()[0]);
323 case PIX_FMT_UYVY422:
325 int const Y = lines(0);
326 int const X = line_size()[0];
327 uint8_t* p = data()[0];
328 for (int y = 0; y < Y; ++y) {
329 for (int x = 0; x < X / 4; ++x) {
330 *p++ = eight_bit_uv; // Cb
332 *p++ = eight_bit_uv; // Cr
340 throw PixelFormatError ("make_black()", _pixel_format);
345 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
347 /* Only implemented for RGBA onto RGB24 so far */
348 assert (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGBA);
350 int start_tx = position.x;
354 start_ox = -start_tx;
358 int start_ty = position.y;
362 start_oy = -start_ty;
366 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
367 uint8_t* tp = data()[0] + ty * stride()[0] + position.x * 3;
368 uint8_t* op = other->data()[0] + oy * other->stride()[0];
369 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
370 float const alpha = float (op[3]) / 255;
371 tp[0] = (tp[0] * (1 - alpha)) + op[0] * alpha;
372 tp[1] = (tp[1] * (1 - alpha)) + op[1] * alpha;
373 tp[2] = (tp[2] * (1 - alpha)) + op[2] * alpha;
381 Image::copy (shared_ptr<const Image> other, Position<int> position)
383 /* Only implemented for RGB24 onto RGB24 so far */
384 assert (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGB24);
385 assert (position.x >= 0 && position.y >= 0);
387 int const N = min (position.x + other->size().width, size().width) - position.x;
388 for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
389 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
390 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
391 memcpy (tp, op, N * 3);
396 Image::read_from_socket (shared_ptr<Socket> socket)
398 for (int i = 0; i < components(); ++i) {
399 uint8_t* p = data()[i];
400 for (int y = 0; y < lines(i); ++y) {
401 socket->read (p, line_size()[i]);
408 Image::write_to_socket (shared_ptr<Socket> socket) const
410 for (int i = 0; i < components(); ++i) {
411 uint8_t* p = data()[i];
412 for (int y = 0; y < lines(i); ++y) {
413 socket->write (p, line_size()[i]);
421 Image::bytes_per_pixel (int c) const
423 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
425 throw PixelFormatError ("lines()", _pixel_format);
428 if (c >= components()) {
432 float bpp[4] = { 0, 0, 0, 0 };
434 bpp[0] = floor ((d->comp[0].depth_minus1 + 1 + 7) / 8);
435 if (d->nb_components > 1) {
436 bpp[1] = floor ((d->comp[1].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
438 if (d->nb_components > 2) {
439 bpp[2] = floor ((d->comp[2].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
441 if (d->nb_components > 3) {
442 bpp[3] = floor ((d->comp[3].depth_minus1 + 1 + 7) / 8) / pow (2.0f, d->log2_chroma_w);
445 if ((d->flags & PIX_FMT_PLANAR) == 0) {
446 /* Not planar; sum them up */
447 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
453 /** Construct a Image of a given size and format, allocating memory
456 * @param p Pixel format.
457 * @param s Size in pixels.
459 Image::Image (AVPixelFormat p, libdcp::Size s, bool aligned)
470 _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
471 _data[0] = _data[1] = _data[2] = _data[3] = 0;
473 _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
474 _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
476 _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
477 _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
479 for (int i = 0; i < components(); ++i) {
480 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
481 _stride[i] = stride_round_up (i, _line_size, _aligned ? 32 : 1);
483 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
484 uses a 16-byte fetch to read three bytes (R/G/B) of image data.
485 Hence on the last pixel of the last line it reads over the end of
486 the actual data by 1 byte. If the width of an image is a multiple
487 of the stride alignment there will be no padding at the end of image lines.
488 OS X crashes on this illegal read, though other operating systems don't
489 seem to mind. The nasty + 1 in this malloc makes sure there is always a byte
490 for that instruction to read safely.
492 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * lines (i) + 1);
496 Image::Image (Image const & other)
497 : libdcp::Image (other)
498 , _pixel_format (other._pixel_format)
499 , _aligned (other._aligned)
503 for (int i = 0; i < components(); ++i) {
504 uint8_t* p = _data[i];
505 uint8_t* q = other._data[i];
506 for (int j = 0; j < lines(i); ++j) {
507 memcpy (p, q, _line_size[i]);
509 q += other.stride()[i];
514 Image::Image (AVFrame* frame)
515 : libdcp::Image (libdcp::Size (frame->width, frame->height))
516 , _pixel_format (static_cast<AVPixelFormat> (frame->format))
521 for (int i = 0; i < components(); ++i) {
522 uint8_t* p = _data[i];
523 uint8_t* q = frame->data[i];
524 for (int j = 0; j < lines(i); ++j) {
525 memcpy (p, q, _line_size[i]);
527 /* AVFrame's linesize is what we call `stride' */
528 q += frame->linesize[i];
533 Image::Image (shared_ptr<const Image> other, bool aligned)
534 : libdcp::Image (other)
535 , _pixel_format (other->_pixel_format)
540 for (int i = 0; i < components(); ++i) {
541 assert(line_size()[i] == other->line_size()[i]);
542 uint8_t* p = _data[i];
543 uint8_t* q = other->data()[i];
544 for (int j = 0; j < lines(i); ++j) {
545 memcpy (p, q, line_size()[i]);
547 q += other->stride()[i];
553 Image::operator= (Image const & other)
555 if (this == &other) {
565 Image::swap (Image & other)
567 libdcp::Image::swap (other);
569 std::swap (_pixel_format, other._pixel_format);
571 for (int i = 0; i < 4; ++i) {
572 std::swap (_data[i], other._data[i]);
573 std::swap (_line_size[i], other._line_size[i]);
574 std::swap (_stride[i], other._stride[i]);
577 std::swap (_aligned, other._aligned);
580 /** Destroy a Image */
583 for (int i = 0; i < components(); ++i) {
588 av_free (_line_size);
599 Image::line_size () const
605 Image::stride () const
617 Image::aligned () const