19 ColorShift::ColorShift() : red_x(0.0), red_y(0.0), green_x(0.0), green_y(0.0), blue_x(0.0), blue_y(0.0), alpha_x(0.0), alpha_y(0.0) {
 
   21     init_effect_details();
 
   26         red_x(red_x), red_y(red_y), green_x(green_x), green_y(green_y), blue_x(blue_x), blue_y(blue_y), alpha_x(alpha_x), alpha_y(alpha_y)
 
   29     init_effect_details();
 
   33 void ColorShift::init_effect_details()
 
   41     info.
description = 
"Shift the colors of an image up, down, left, and right (with infinite wrapping).";
 
   48 std::shared_ptr<openshot::Frame> 
ColorShift::GetFrame(std::shared_ptr<openshot::Frame> frame, int64_t frame_number)
 
   51     std::shared_ptr<QImage> frame_image = frame->GetImage();
 
   52     unsigned char *pixels = (
unsigned char *) frame_image->bits();
 
   55     int frame_image_width = frame_image->width();
 
   56     int frame_image_height = frame_image->height();
 
   61     int red_x_shift_limit = round(frame_image_width * fmod(fabs(red_x_shift), 1.0));
 
   63     int red_y_shift_limit = round(frame_image_height * fmod(fabs(red_y_shift), 1.0));
 
   66     int green_x_shift_limit = round(frame_image_width * fmod(fabs(green_x_shift), 1.0));
 
   68     int green_y_shift_limit = round(frame_image_height * fmod(fabs(green_y_shift), 1.0));
 
   71     int blue_x_shift_limit = round(frame_image_width * fmod(fabs(blue_x_shift), 1.0));
 
   73     int blue_y_shift_limit = round(frame_image_height * fmod(fabs(blue_y_shift), 1.0));
 
   76     int alpha_x_shift_limit = round(frame_image_width * fmod(fabs(alpha_x_shift), 1.0));
 
   78     int alpha_y_shift_limit = round(frame_image_height * fmod(fabs(alpha_y_shift), 1.0));
 
   81     unsigned char *temp_image = 
new unsigned char[frame_image_width * frame_image_height * 4]();
 
   82     memcpy(temp_image, pixels, 
sizeof(
char) * frame_image_width * frame_image_height * 4);
 
   85     int starting_row_index = 0;
 
   94     int red_starting_row_index = 0;
 
   95     int green_starting_row_index = 0;
 
   96     int blue_starting_row_index = 0;
 
   97     int alpha_starting_row_index = 0;
 
   99     int red_pixel_offset = 0;
 
  100     int green_pixel_offset = 0;
 
  101     int blue_pixel_offset = 0;
 
  102     int alpha_pixel_offset = 0;
 
  105     for (
int row = 0; row < frame_image_height; row++) {
 
  106         for (
int col = 0; col < frame_image_width; col++) {
 
  108             starting_row_index = row * frame_image_width * 4;
 
  109             byte_index = starting_row_index + (col * 4);
 
  110             red_starting_row_index = starting_row_index;
 
  111             green_starting_row_index = starting_row_index;
 
  112             blue_starting_row_index = starting_row_index;
 
  113             alpha_starting_row_index = starting_row_index;
 
  115             red_pixel_offset = col;
 
  116             green_pixel_offset = col;
 
  117             blue_pixel_offset = col;
 
  118             alpha_pixel_offset = col;
 
  121             R = temp_image[byte_index];
 
  122             G = temp_image[byte_index + 1];
 
  123             B = temp_image[byte_index + 2];
 
  124             A = temp_image[byte_index + 3];
 
  127             if (red_x_shift > 0.0)
 
  128                 red_pixel_offset = (col + red_x_shift_limit) % frame_image_width;
 
  129             if (red_x_shift < 0.0)
 
  130                 red_pixel_offset = (frame_image_width + col - red_x_shift_limit) % frame_image_width;
 
  131             if (green_x_shift > 0.0)
 
  132                 green_pixel_offset = (col + green_x_shift_limit) % frame_image_width;
 
  133             if (green_x_shift < 0.0)
 
  134                 green_pixel_offset = (frame_image_width + col - green_x_shift_limit) % frame_image_width;
 
  135             if (blue_x_shift > 0.0)
 
  136                 blue_pixel_offset = (col + blue_x_shift_limit) % frame_image_width;
 
  137             if (blue_x_shift < 0.0)
 
  138                 blue_pixel_offset = (frame_image_width + col - blue_x_shift_limit) % frame_image_width;
 
  139             if (alpha_x_shift > 0.0)
 
  140                 alpha_pixel_offset = (col + alpha_x_shift_limit) % frame_image_width;
 
  141             if (alpha_x_shift < 0.0)
 
  142                 alpha_pixel_offset = (frame_image_width + col - alpha_x_shift_limit) % frame_image_width;
 
  145             if (red_y_shift > 0.0)
 
  146                 red_starting_row_index = ((row + red_y_shift_limit) % frame_image_height) * frame_image_width * 4;
 
  147             if (red_y_shift < 0.0)
 
  148                 red_starting_row_index = ((frame_image_height + row - red_y_shift_limit) % frame_image_height) * frame_image_width * 4;
 
  149             if (green_y_shift > 0.0)
 
  150                 green_starting_row_index = ((row + green_y_shift_limit) % frame_image_height) * frame_image_width * 4;
 
  151             if (green_y_shift < 0.0)
 
  152                 green_starting_row_index = ((frame_image_height + row - green_y_shift_limit) % frame_image_height) * frame_image_width * 4;
 
  153             if (blue_y_shift > 0.0)
 
  154                 blue_starting_row_index = ((row + blue_y_shift_limit) % frame_image_height) * frame_image_width * 4;
 
  155             if (blue_y_shift < 0.0)
 
  156                 blue_starting_row_index = ((frame_image_height + row - blue_y_shift_limit) % frame_image_height) * frame_image_width * 4;
 
  157             if (alpha_y_shift > 0.0)
 
  158                 alpha_starting_row_index = ((row + alpha_y_shift_limit) % frame_image_height) * frame_image_width * 4;
 
  159             if (alpha_y_shift < 0.0)
 
  160                 alpha_starting_row_index = ((frame_image_height + row - alpha_y_shift_limit) % frame_image_height) * frame_image_width * 4;
 
  163             pixels[red_starting_row_index + 0 + (red_pixel_offset * 4)] = R;
 
  164             pixels[green_starting_row_index + 1 + (green_pixel_offset * 4)] = G;
 
  165             pixels[blue_starting_row_index + 2 + (blue_pixel_offset * 4)] = B;
 
  166             pixels[alpha_starting_row_index + 3 + (alpha_pixel_offset * 4)] = A;
 
  213     catch (
const std::exception& e)
 
  216         throw InvalidJSON(
"JSON is invalid (missing keys or invalid data types)");
 
  227     if (!root[
"red_x"].isNull())
 
  229     if (!root[
"red_y"].isNull())
 
  231     if (!root[
"green_x"].isNull())
 
  233     if (!root[
"green_y"].isNull())
 
  235     if (!root[
"blue_x"].isNull())
 
  237     if (!root[
"blue_y"].isNull())
 
  239     if (!root[
"alpha_x"].isNull())
 
  241     if (!root[
"alpha_y"].isNull())
 
  262     return root.toStyledString();