X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fimage.cc;h=c3b1ca77afded0cc70270fb097d40a6b989a2bfa;hb=2e504b33eb9f38cac629ad31b7c107fb0cf5efda;hp=b706f7fdc3f68fdcf7b611835631ce315eff016a;hpb=cc3900735839ff4b0da0c046b5c606c440ba917a;p=dcpomatic.git diff --git a/src/lib/image.cc b/src/lib/image.cc index b706f7fdc..c3b1ca77a 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Carl Hetherington + Copyright (C) 2012-2014 Carl Hetherington This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -33,9 +33,12 @@ extern "C" { #include "scaler.h" #include "timer.h" +#include "i18n.h" + using std::string; using std::min; using std::cout; +using std::cerr; using boost::shared_ptr; using dcp::Size; @@ -89,26 +92,38 @@ Image::crop_scale_window (Crop crop, dcp::Size inter_size, dcp::Size out_size, S */ assert (aligned ()); + assert (out_size.width >= inter_size.width); + assert (out_size.height >= inter_size.height); + + /* Here's an image of out_size */ shared_ptr out (new Image (out_format, out_size, out_aligned)); out->make_black (); - - dcp::Size cropped_size = crop.apply (size ()); + /* Size of the image after any crop */ + dcp::Size const cropped_size = crop.apply (size ()); + + /* Scale context for a scale from cropped_size to inter_size */ struct SwsContext* scale_context = sws_getContext ( cropped_size.width, cropped_size.height, pixel_format(), inter_size.width, inter_size.height, out_format, scaler->ffmpeg_id (), 0, 0, 0 ); + if (!scale_context) { + throw StringError (N_("Could not allocate SwsContext")); + } + + /* Prepare input data pointers with crop */ uint8_t* scale_in_data[components()]; for (int c = 0; c < components(); ++c) { scale_in_data[c] = data()[c] + int (rint (bytes_per_pixel(c) * crop.left)) + stride()[c] * (crop.top / line_factor(c)); } + /* Corner of the image within out_size */ Position const corner ((out_size.width - inter_size.width) / 2, (out_size.height - inter_size.height) / 2); - uint8_t* scale_out_data[components()]; - for (int c = 0; c < components(); ++c) { + uint8_t* scale_out_data[out->components()]; + for (int c = 0; c < out->components(); ++c) { scale_out_data[c] = out->data()[c] + int (rint (out->bytes_per_pixel(c) * corner.x)) + out->stride()[c] * corner.y; } @@ -153,51 +168,6 @@ Image::scale (dcp::Size out_size, Scaler const * scaler, AVPixelFormat out_forma return scaled; } -/** Run a FFmpeg post-process on this image and return the processed version. - * @param pp Flags for the required set of post processes. - * @return Post-processed image. - */ -shared_ptr -Image::post_process (string pp, bool aligned) const -{ - shared_ptr out (new Image (pixel_format(), size (), aligned)); - - int pp_format = 0; - switch (pixel_format()) { - case PIX_FMT_YUV420P: - pp_format = PP_FORMAT_420; - break; - case PIX_FMT_YUV422P10LE: - case PIX_FMT_YUV422P: - case PIX_FMT_UYVY422: - pp_format = PP_FORMAT_422; - break; - case PIX_FMT_YUV444P: - case PIX_FMT_YUV444P9BE: - case PIX_FMT_YUV444P9LE: - case PIX_FMT_YUV444P10BE: - case PIX_FMT_YUV444P10LE: - pp_format = PP_FORMAT_444; - default: - throw PixelFormatError ("post_process", pixel_format()); - } - - pp_mode* mode = pp_get_mode_by_name_and_quality (pp.c_str (), PP_QUALITY_MAX); - pp_context* context = pp_get_context (size().width, size().height, pp_format | PP_CPU_CAPS_MMX2); - - pp_postprocess ( - (const uint8_t **) data(), stride(), - out->data(), out->stride(), - size().width, size().height, - 0, 0, mode, context, 0 - ); - - pp_free_mode (mode); - pp_free_context (context); - - return out; -} - shared_ptr Image::crop (Crop crop, bool aligned) const {