File: padding_effect.cpp

package info (click to toggle)
movit 1.7.2-1
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 3,248 kB
  • sloc: cpp: 16,677; sh: 3,940; makefile: 167
file content (151 lines) | stat: -rw-r--r-- 5,115 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include <epoxy/gl.h>
#include <assert.h>

#include "effect_util.h"
#include "padding_effect.h"
#include "util.h"

using namespace std;

namespace movit {

PaddingEffect::PaddingEffect()
	: border_color(0.0f, 0.0f, 0.0f, 0.0f),
	  output_width(1280),
	  output_height(720),
	  top(0),
	  left(0),
	  border_offset_top(0.0f),
	  border_offset_left(0.0f),
	  border_offset_bottom(0.0f),
	  border_offset_right(0.0f)
{
	register_vec4("border_color", (float *)&border_color);
	register_int("width", &output_width);
	register_int("height", &output_height);
	register_float("top", &top);
	register_float("left", &left);
	register_float("border_offset_top", &border_offset_top);
	register_float("border_offset_left", &border_offset_left);
	register_float("border_offset_bottom", &border_offset_bottom);
	register_float("border_offset_right", &border_offset_right);
	register_uniform_vec2("offset", uniform_offset);
	register_uniform_vec2("scale", uniform_scale);
	register_uniform_vec2("normalized_coords_to_texels", uniform_normalized_coords_to_texels);
	register_uniform_vec2("offset_bottomleft", uniform_offset_bottomleft);
	register_uniform_vec2("offset_topright", uniform_offset_topright);
}

string PaddingEffect::output_fragment_shader()
{
	return read_file("padding_effect.frag");
}

void PaddingEffect::set_gl_state(GLuint glsl_program_num, const string &prefix, unsigned *sampler_num)
{
	Effect::set_gl_state(glsl_program_num, prefix, sampler_num);

	uniform_offset[0] = left / output_width;
	uniform_offset[1] = (output_height - input_height - top) / output_height;

	uniform_scale[0] = float(output_width) / input_width;
	uniform_scale[1] = float(output_height) / input_height;

	uniform_normalized_coords_to_texels[0] = float(input_width);
	uniform_normalized_coords_to_texels[1] = float(input_height);

	// Texels -0.5..0.5 should map to light level 0..1 (and then we
	// clamp the rest).
	uniform_offset_bottomleft[0] = 0.5f - border_offset_left;
	uniform_offset_bottomleft[1] = 0.5f + border_offset_bottom;

	// Texels size-0.5..size+0.5 should map to light level 1..0 (and then clamp).
	uniform_offset_topright[0] = input_width + 0.5f + border_offset_right;
	uniform_offset_topright[1] = input_height + 0.5f - border_offset_top;
}
	
// We don't change the pixels of the image itself, so the only thing that 
// can make us less flexible is if the border color can be interpreted
// differently in different modes.

// 0.0 and 1.0 are interpreted the same, no matter the gamma ramp.
// Alpha is not affected by gamma per se, but the combination of
// premultiplied alpha and non-linear gamma curve does not make sense,
// so if could possibly be converting blank alpha to non-blank
// (ie., premultiplied), we need our output to be in linear light.
bool PaddingEffect::needs_linear_light() const
{
	if ((border_color.r == 0.0 || border_color.r == 1.0) &&
	    (border_color.g == 0.0 || border_color.g == 1.0) &&
	    (border_color.b == 0.0 || border_color.b == 1.0) &&
	    border_color.a == 1.0) {
		return false;
	}
	return true;
}

// The white point is the same (D65) in all the color spaces we currently support,
// so any gray would be okay, but we don't really have a guarantee for that.
// Stay safe and say that only pure black and pure white is okay.
// Alpha is not affected by color space.
bool PaddingEffect::needs_srgb_primaries() const
{
	if (border_color.r == 0.0 && border_color.g == 0.0 && border_color.b == 0.0) {
		return false;
	}
	if (border_color.r == 1.0 && border_color.g == 1.0 && border_color.b == 1.0) {
		return false;
	}
	return true;
}

Effect::AlphaHandling PaddingEffect::alpha_handling() const
{
	// If the border color is solid, it doesn't matter if we're pre- or postmultiplied.
	if (border_color.a == 1.0) {
		return DONT_CARE_ALPHA_TYPE;
	}

	// Otherwise, we're going to output our border color in premultiplied alpha,
	// so the other pixels better be premultiplied as well.
	// Note that for non-solid black (i.e. alpha < 1.0), we're equally fine with
	// pre- and postmultiplied, but we are _not_ fine with blank being passed through,
	// and we don't have a way to specify that.
	return INPUT_AND_OUTPUT_PREMULTIPLIED_ALPHA;
}
	
void PaddingEffect::get_output_size(unsigned *width, unsigned *height, unsigned *virtual_width, unsigned *virtual_height) const
{
	*virtual_width = *width = output_width;
	*virtual_height = *height = output_height;
}
	
void PaddingEffect::inform_input_size(unsigned input_num, unsigned width, unsigned height)
{
	assert(input_num == 0);
	input_width = width;
	input_height = height;
}

IntegralPaddingEffect::IntegralPaddingEffect() {}

bool IntegralPaddingEffect::set_int(const std::string &key, int value)
{
	if (key == "top" || key == "left") {
		return PaddingEffect::set_float(key, value);
	} else {
		return PaddingEffect::set_int(key, value);
	}
}

bool IntegralPaddingEffect::set_float(const std::string &key, float value)
{
	if (key == "top" || key == "left") {
		// These are removed as float parameters from this version.
		return false;
	} else {
		return PaddingEffect::set_float(key, value);
	}
}

}  // namespace movit