19 Blur::Blur() : horizontal_radius(6.0), vertical_radius(6.0), sigma(3.0), iterations(3.0) {
 
   21     init_effect_details();
 
   26         horizontal_radius(new_horizontal_radius), vertical_radius(new_vertical_radius),
 
   27         sigma(new_sigma), iterations(new_iterations)
 
   30     init_effect_details();
 
   34 void Blur::init_effect_details()
 
   49 std::shared_ptr<openshot::Frame> 
Blur::GetFrame(std::shared_ptr<openshot::Frame> frame, int64_t frame_number)
 
   52     std::shared_ptr<QImage> frame_image = frame->GetImage();
 
   60     int w = frame_image->width();
 
   61     int h = frame_image->height();
 
   64     QImage image_copy = frame_image->copy();
 
   65     std::shared_ptr<QImage> frame_image_2 = std::make_shared<QImage>(image_copy);
 
   68     for (
int iteration = 0; iteration < iteration_value; ++iteration)
 
   71         if (horizontal_radius_value > 0.0) {
 
   73             boxBlurH(frame_image->bits(), frame_image_2->bits(), w, h, horizontal_radius_value);
 
   76             frame_image.swap(frame_image_2);
 
   80         if (vertical_radius_value > 0.0) {
 
   82             boxBlurT(frame_image->bits(), frame_image_2->bits(), w, h, vertical_radius_value);
 
   85             frame_image.swap(frame_image_2);
 
   95 void Blur::boxBlurH(
unsigned char *scl, 
unsigned char *tcl, 
int w, 
int h, 
int r) {
 
   96     float iarr = 1.0 / (r + r + 1);
 
   98     #pragma omp parallel for shared (scl, tcl) 
   99     for (
int i = 0; i < h; ++i) {
 
  100         for (
int ch = 0; ch < 4; ++ch) {
 
  101             int ti = i * w, li = ti, ri = ti + r;
 
  102             int fv = scl[ti * 4 + ch], lv = scl[(ti + w - 1) * 4 + ch], val = (r + 1) * fv;
 
  103             for (
int j = 0; j < r; ++j) {
 
  104                 val += scl[(ti + j) * 4 + ch];
 
  106             for (
int j = 0; j <= r; ++j) {
 
  107                 val += scl[ri++ * 4 + ch] - fv;
 
  108                 tcl[ti++ * 4 + ch] = round(val * iarr);
 
  110             for (
int j = r + 1; j < w - r; ++j) {
 
  111                 val += scl[ri++ * 4 + ch] - scl[li++ * 4 + ch];
 
  112                 tcl[ti++ * 4 + ch] = round(val * iarr);
 
  114             for (
int j = w - r; j < w; ++j) {
 
  115                 val += lv - scl[li++ * 4 + ch];
 
  116                 tcl[ti++ * 4 + ch] = round(val * iarr);
 
  122 void Blur::boxBlurT(
unsigned char *scl, 
unsigned char *tcl, 
int w, 
int h, 
int r) {
 
  123     float iarr = 1.0 / (r + r + 1);
 
  125     #pragma omp parallel for shared (scl, tcl) 
  126     for (
int i = 0; i < w; i++) {
 
  127         for (
int ch = 0; ch < 4; ++ch) {
 
  128             int ti = i, li = ti, ri = ti + r * w;
 
  129             int fv = scl[ti * 4 + ch], lv = scl[(ti + w * (h - 1)) * 4 + ch], val = (r + 1) * fv;
 
  130             for (
int j = 0; j < r; j++) val += scl[(ti + j * w) * 4 + ch];
 
  131             for (
int j = 0; j <= r; j++) {
 
  132                 val += scl[ri * 4 + ch] - fv;
 
  133                 tcl[ti * 4 + ch] = round(val * iarr);
 
  137             for (
int j = r + 1; j < h - r; j++) {
 
  138                 val += scl[ri * 4 + ch] - scl[li * 4 + ch];
 
  139                 tcl[ti * 4 + ch] = round(val * iarr);
 
  144             for (
int j = h - r; j < h; j++) {
 
  145                 val += lv - scl[li * 4 + ch];
 
  146                 tcl[ti * 4 + ch] = round(val * iarr);
 
  186     catch (
const std::exception& e)
 
  189         throw InvalidJSON(
"JSON is invalid (missing keys or invalid data types)");
 
  200     if (!root[
"horizontal_radius"].isNull())
 
  202     if (!root[
"vertical_radius"].isNull())
 
  204     if (!root[
"sigma"].isNull())
 
  206     if (!root[
"iterations"].isNull())
 
  223     return root.toStyledString();