4 #include "effect_util.h"
5 #include "padding_effect.h"
12 PaddingEffect::PaddingEffect()
13 : border_color(0.0f, 0.0f, 0.0f, 0.0f),
18 border_offset_top(0.0f),
19 border_offset_left(0.0f),
20 border_offset_bottom(0.0f),
21 border_offset_right(0.0f)
23 register_vec4("border_color", (float *)&border_color);
24 register_int("width", &output_width);
25 register_int("height", &output_height);
26 register_float("top", &top);
27 register_float("left", &left);
28 register_float("border_offset_top", &border_offset_top);
29 register_float("border_offset_left", &border_offset_left);
30 register_float("border_offset_bottom", &border_offset_bottom);
31 register_float("border_offset_right", &border_offset_right);
32 register_uniform_vec2("offset", uniform_offset);
33 register_uniform_vec2("scale", uniform_scale);
34 register_uniform_vec2("normalized_coords_to_texels", uniform_normalized_coords_to_texels);
35 register_uniform_vec2("offset_bottomleft", uniform_offset_bottomleft);
36 register_uniform_vec2("offset_topright", uniform_offset_topright);
39 string PaddingEffect::output_fragment_shader()
41 return read_file("padding_effect.frag");
44 void PaddingEffect::set_gl_state(GLuint glsl_program_num, const string &prefix, unsigned *sampler_num)
46 Effect::set_gl_state(glsl_program_num, prefix, sampler_num);
48 uniform_offset[0] = left / output_width;
49 uniform_offset[1] = (output_height - input_height - top) / output_height;
51 uniform_scale[0] = float(output_width) / input_width;
52 uniform_scale[1] = float(output_height) / input_height;
54 uniform_normalized_coords_to_texels[0] = float(input_width);
55 uniform_normalized_coords_to_texels[1] = float(input_height);
57 // Texels -0.5..0.5 should map to light level 0..1 (and then we
59 uniform_offset_bottomleft[0] = 0.5f - border_offset_left;
60 uniform_offset_bottomleft[1] = 0.5f + border_offset_bottom;
62 // Texels size-0.5..size+0.5 should map to light level 1..0 (and then clamp).
63 uniform_offset_topright[0] = input_width + 0.5f + border_offset_right;
64 uniform_offset_topright[1] = input_height + 0.5f - border_offset_top;
67 // We don't change the pixels of the image itself, so the only thing that
68 // can make us less flexible is if the border color can be interpreted
69 // differently in different modes.
71 // 0.0 and 1.0 are interpreted the same, no matter the gamma ramp.
72 // Alpha is not affected by gamma per se, but the combination of
73 // premultiplied alpha and non-linear gamma curve does not make sense,
74 // so if could possibly be converting blank alpha to non-blank
75 // (ie., premultiplied), we need our output to be in linear light.
76 bool PaddingEffect::needs_linear_light() const
78 if ((border_color.r == 0.0 || border_color.r == 1.0) &&
79 (border_color.g == 0.0 || border_color.g == 1.0) &&
80 (border_color.b == 0.0 || border_color.b == 1.0) &&
81 border_color.a == 1.0) {
87 // The white point is the same (D65) in all the color spaces we currently support,
88 // so any gray would be okay, but we don't really have a guarantee for that.
89 // Stay safe and say that only pure black and pure white is okay.
90 // Alpha is not affected by color space.
91 bool PaddingEffect::needs_srgb_primaries() const
93 if (border_color.r == 0.0 && border_color.g == 0.0 && border_color.b == 0.0) {
96 if (border_color.r == 1.0 && border_color.g == 1.0 && border_color.b == 1.0) {
102 Effect::AlphaHandling PaddingEffect::alpha_handling() const
104 // If the border color is black, it doesn't matter if we're pre- or postmultiplied.
105 // Note that for non-solid black (i.e. alpha < 1.0), we're equally fine with
106 // pre- and postmultiplied, but later effects might change this status
107 // (consider e.g. blur), so setting DONT_CARE_ALPHA_TYPE is inappropriate,
108 // as it propagate blank alpha through this effect.
109 if (border_color.r == 0.0 && border_color.g == 0.0 && border_color.b == 0.0 && border_color.a == 1.0) {
110 return DONT_CARE_ALPHA_TYPE;
113 // If the border color is solid, we preserve blank alpha, as we never output any
114 // new non-solid pixels.
115 if (border_color.a == 1.0) {
116 return INPUT_PREMULTIPLIED_ALPHA_KEEP_BLANK;
119 // Otherwise, we're going to output our border color in premultiplied alpha,
120 // so the other pixels better be premultiplied as well.
121 return INPUT_AND_OUTPUT_PREMULTIPLIED_ALPHA;
124 void PaddingEffect::get_output_size(unsigned *width, unsigned *height, unsigned *virtual_width, unsigned *virtual_height) const
126 *virtual_width = *width = output_width;
127 *virtual_height = *height = output_height;
130 void PaddingEffect::inform_input_size(unsigned input_num, unsigned width, unsigned height)
132 assert(input_num == 0);
134 input_height = height;
137 IntegralPaddingEffect::IntegralPaddingEffect() {}
139 bool IntegralPaddingEffect::set_int(const std::string &key, int value)
141 if (key == "top" || key == "left") {
142 return PaddingEffect::set_float(key, value);
144 return PaddingEffect::set_int(key, value);
148 bool IntegralPaddingEffect::set_float(const std::string &key, float value)
150 if (key == "top" || key == "left") {
151 // These are removed as float parameters from this version.
154 return PaddingEffect::set_float(key, value);