28 #include "../../include/effects/Blur.h"
33 Blur::Blur() : horizontal_radius(6.0), vertical_radius(6.0), sigma(3.0), iterations(3.0) {
35 init_effect_details();
40 horizontal_radius(new_horizontal_radius), vertical_radius(new_vertical_radius),
41 sigma(new_sigma), iterations(new_iterations)
44 init_effect_details();
48 void Blur::init_effect_details()
63 std::shared_ptr<Frame>
Blur::GetFrame(std::shared_ptr<Frame> frame, int64_t frame_number)
66 std::shared_ptr<QImage> frame_image = frame->GetImage();
76 unsigned char *red =
new unsigned char[frame_image->width() * frame_image->height()]();
77 unsigned char *green =
new unsigned char[frame_image->width() * frame_image->height()]();
78 unsigned char *blue =
new unsigned char[frame_image->width() * frame_image->height()]();
79 unsigned char *alpha =
new unsigned char[frame_image->width() * frame_image->height()]();
81 unsigned char *blur_red =
new unsigned char[frame_image->width() * frame_image->height()]();
82 unsigned char *blur_green =
new unsigned char[frame_image->width() * frame_image->height()]();
83 unsigned char *blur_blue =
new unsigned char[frame_image->width() * frame_image->height()]();
84 unsigned char *blur_alpha =
new unsigned char[frame_image->width() * frame_image->height()]();
87 unsigned char *pixels = (
unsigned char *) frame_image->bits();
88 for (
int pixel = 0, byte_index=0; pixel < frame_image->width() * frame_image->height(); pixel++, byte_index+=4)
91 unsigned char R = pixels[byte_index];
92 unsigned char G = pixels[byte_index + 1];
93 unsigned char B = pixels[byte_index + 2];
94 unsigned char A = pixels[byte_index + 3];
104 for (
int i = 0; i < (frame_image->width() * frame_image->height()); i++) blur_red[i] = red[i];
105 for (
int i = 0; i < (frame_image->width() * frame_image->height()); i++) blur_green[i] = green[i];
106 for (
int i = 0; i < (frame_image->width() * frame_image->height()); i++) blur_blue[i] = blue[i];
107 for (
int i = 0; i < (frame_image->width() * frame_image->height()); i++) blur_alpha[i] = alpha[i];
110 for (
int iteration = 0; iteration < iteration_value; iteration++)
113 if (horizontal_radius_value > 0.0) {
115 int *bxs = initBoxes(sigma_value, horizontal_radius_value);
118 boxBlurH(red, blur_red, frame_image->width(), frame_image->height(), horizontal_radius_value);
119 boxBlurH(green, blur_green, frame_image->width(), frame_image->height(), horizontal_radius_value);
120 boxBlurH(blue, blur_blue, frame_image->width(), frame_image->height(), horizontal_radius_value);
121 boxBlurH(alpha, blur_alpha, frame_image->width(), frame_image->height(), horizontal_radius_value);
127 for (
int i = 0; i < (frame_image->width() * frame_image->height()); i++) red[i] = blur_red[i];
128 for (
int i = 0; i < (frame_image->width() * frame_image->height()); i++) green[i] = blur_green[i];
129 for (
int i = 0; i < (frame_image->width() * frame_image->height()); i++) blue[i] = blur_blue[i];
130 for (
int i = 0; i < (frame_image->width() * frame_image->height()); i++) alpha[i] = blur_alpha[i];
134 if (vertical_radius_value > 0.0) {
136 int *bxs = initBoxes(sigma_value, vertical_radius_value);
139 boxBlurT(red, blur_red, frame_image->width(), frame_image->height(), vertical_radius_value);
140 boxBlurT(green, blur_green, frame_image->width(), frame_image->height(), vertical_radius_value);
141 boxBlurT(blue, blur_blue, frame_image->width(), frame_image->height(), vertical_radius_value);
142 boxBlurT(alpha, blur_alpha, frame_image->width(), frame_image->height(), vertical_radius_value);
148 for (
int i = 0; i < (frame_image->width() * frame_image->height()); i++) red[i] = blur_red[i];
149 for (
int i = 0; i < (frame_image->width() * frame_image->height()); i++) green[i] = blur_green[i];
150 for (
int i = 0; i < (frame_image->width() * frame_image->height()); i++) blue[i] = blur_blue[i];
151 for (
int i = 0; i < (frame_image->width() * frame_image->height()); i++) alpha[i] = blur_alpha[i];
156 for (
int pixel = 0, byte_index=0; pixel < frame_image->width() * frame_image->height(); pixel++, byte_index+=4)
159 unsigned char R = blur_red[pixel];
160 unsigned char G = blur_green[pixel];
161 unsigned char B = blur_blue[pixel];
162 unsigned char A = blur_alpha[pixel];
165 pixels[byte_index] = R;
166 pixels[byte_index + 1] = G;
167 pixels[byte_index + 2] = B;
168 pixels[byte_index + 3] = A;
186 int* Blur::initBoxes(
float sigma,
int n)
188 float wIdeal = sqrt((12.0 *
sigma *
sigma / n) + 1.0);
189 int wl = floor(wIdeal);
190 if (wl % 2 == 0) wl--;
193 float mIdeal = (12.0 *
sigma *
sigma - n * wl * wl - 4 * n * wl - 3 * n) / (-4.0 * wl - 4);
194 int m = round(mIdeal);
196 int *sizes =
new int[n]();
197 for (
int i = 0; i < n; i++) sizes[i] = i < m ? wl : wu;
202 void Blur::boxBlurH(
unsigned char *scl,
unsigned char *tcl,
int w,
int h,
int r) {
203 float iarr = 1.0 / (r + r + 1);
204 for (
int i = 0; i < h; i++) {
205 int ti = i * w, li = ti, ri = ti + r;
206 int fv = scl[ti], lv = scl[ti + w - 1], val = (r + 1) * fv;
207 for (
int j = 0; j < r; j++) val += scl[ti + j];
208 for (
int j = 0; j <= r; j++) {
209 val += scl[ri++] - fv;
210 tcl[ti++] = round(val * iarr);
212 for (
int j = r + 1; j < w - r; j++) {
213 val += scl[ri++] - scl[li++];
214 tcl[ti++] = round(val * iarr);
216 for (
int j = w - r; j < w; j++) {
217 val += lv - scl[li++];
218 tcl[ti++] = round(val * iarr);
223 void Blur::boxBlurT(
unsigned char *scl,
unsigned char *tcl,
int w,
int h,
int r) {
224 float iarr = 1.0 / (r + r + 1);
225 for (
int i = 0; i < w; i++) {
226 int ti = i, li = ti, ri = ti + r * w;
227 int fv = scl[ti], lv = scl[ti + w * (h - 1)], val = (r + 1) * fv;
228 for (
int j = 0; j < r; j++) val += scl[ti + j * w];
229 for (
int j = 0; j <= r; j++) {
231 tcl[ti] = round(val * iarr);
235 for (
int j = r + 1; j < h - r; j++) {
236 val += scl[ri] - scl[li];
237 tcl[ti] = round(val * iarr);
242 for (
int j = h - r; j < h; j++) {
244 tcl[ti] = round(val * iarr);
279 bool success = reader.parse( value, root );
282 throw InvalidJSON(
"JSON could not be parsed (or is invalid)",
"");
292 throw InvalidJSON(
"JSON is invalid (missing keys or invalid data types)",
"");
303 if (!root[
"horizontal_radius"].isNull())
305 if (!root[
"vertical_radius"].isNull())
307 if (!root[
"sigma"].isNull())
309 if (!root[
"iterations"].isNull())
318 root[
"id"] =
add_property_json(
"ID", 0.0,
"string",
Id(), NULL, -1, -1,
true, requested_frame);
319 root[
"position"] =
add_property_json(
"Position",
Position(),
"float",
"", NULL, 0, 1000 * 60 * 30,
false, requested_frame);
321 root[
"start"] =
add_property_json(
"Start",
Start(),
"float",
"", NULL, 0, 1000 * 60 * 30,
false, requested_frame);
322 root[
"end"] =
add_property_json(
"End",
End(),
"float",
"", NULL, 0, 1000 * 60 * 30,
false, requested_frame);
323 root[
"duration"] =
add_property_json(
"Duration",
Duration(),
"float",
"", NULL, 0, 1000 * 60 * 30,
true, requested_frame);
332 return root.toStyledString();