diff options
Diffstat (limited to 'libhb/rotate.c')
-rw-r--r-- | libhb/rotate.c | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/libhb/rotate.c b/libhb/rotate.c new file mode 100644 index 000000000..7ba140514 --- /dev/null +++ b/libhb/rotate.c @@ -0,0 +1,146 @@ +/* rotate.c + + Copyright (c) 2003-2015 HandBrake Team + This file is part of the HandBrake source code + Homepage: <http://handbrake.fr/>. + It may be used under the terms of the GNU General Public License v2. + For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html + */ + +#include "common.h" +#include "avfilter_priv.h" + +static int rotate_init(hb_filter_object_t * filter, hb_filter_init_t * init); + +const char rotate_template[] = + "angle=^(0|90|180|270)$:hflip=^"HB_BOOL_REG"$:disable=^"HB_BOOL_REG"$"; + +hb_filter_object_t hb_filter_rotate = +{ + .id = HB_FILTER_ROTATE, + .enforce_order = 1, + .skip = 1, + .name = "Rotate", + .settings = NULL, + .init = rotate_init, + .work = hb_avfilter_null_work, + .close = hb_avfilter_alias_close, + .settings_template = rotate_template, +}; + +/* Rotate Settings: + * degrees:mirror + * + * degrees - Rotation angle, may be one of 90, 180, or 270 + * mirror - Mirror image around x axis + * + * Examples: + * Mode 180:1 Mirror then rotate 180' + * Mode 0:1 Mirror + * Mode 180:0 Rotate 180' + * Mode 90:0 Rotate 90' + * Mode 270:0 Rotate 270' + * + * Legacy Mode Examples (also accepted): + * Mode 1: Flip vertically (y0 becomes yN and yN becomes y0) (aka 180:1) + * Mode 2: Flip horizontally (x0 becomes xN and xN becomes x0) (aka 0:1) + * Mode 3: Flip both horizontally and vertically (aka 180:0) + * Mode 4: Rotate 90' (aka 90:0) + * Mode 7: Flip horiz & vert plus Rotate 90' (aka 270:0) + */ +static int rotate_init(hb_filter_object_t * filter, hb_filter_init_t * init) +{ + hb_filter_private_t * pv = NULL; + + pv = calloc(1, sizeof(struct hb_filter_private_s)); + filter->private_data = pv; + if (pv == NULL) + { + return 1; + } + pv->input = *init; + + hb_dict_t * settings = filter->settings; + + int width = init->geometry.width; + int height = init->geometry.height; + const char * trans = NULL; + int angle = 0, flip = 0, hflip = 0, vflip = 0, tmp; + + hb_dict_extract_int(&angle, settings, "angle"); + hb_dict_extract_bool(&flip, settings, "hflip"); + + const char * clock; + const char * cclock; + if (flip) + { + clock = "clock_flip"; + cclock = "cclock_flip"; + } + else + { + clock = "clock"; + cclock = "cclock"; + } + switch (angle) + { + case 0: + hflip = flip; + break; + case 90: + trans = clock; + tmp = width; + width = height; + height = tmp; + break; + case 180: + vflip = 1; + hflip = !flip; + break; + case 270: + trans = cclock; + tmp = width; + width = height; + height = tmp; + break; + default: + break; + } + if (trans != NULL) + { + hb_dict_t * avfilter = hb_dict_init(); + hb_dict_t * avsettings = hb_dict_init(); + + hb_dict_set(avsettings, "dir", hb_value_string(trans)); + hb_dict_set(avfilter, "transpose", avsettings); + pv->avfilters = avfilter; + } + else if (hflip || vflip) + { + hb_value_array_t * avfilters = hb_value_array_init(); + hb_dict_t * avfilter; + if (vflip) + { + avfilter = hb_dict_init(); + hb_dict_set(avfilter, "vflip", hb_value_null()); + hb_value_array_append(avfilters, avfilter); + } + if (hflip) + { + avfilter = hb_dict_init(); + hb_dict_set(avfilter, "hflip", hb_value_null()); + hb_value_array_append(avfilters, avfilter); + } + pv->avfilters = avfilter; + } + else + { + pv->avfilters = hb_value_null(); + } + + init->geometry.width = width; + init->geometry.height = height; + pv->output = *init; + + return 0; +} |