31 #include "../../include/effects/ColorShift.h"
36 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) {
38 init_effect_details();
43 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)
46 init_effect_details();
50 void ColorShift::init_effect_details()
58 info.
description =
"Shift the colors of an image up, down, left, and right (with infinite wrapping).";
68 std::shared_ptr<QImage> frame_image = frame->
GetImage();
69 unsigned char *pixels = (
unsigned char *) frame_image->bits();
72 int frame_image_width = frame_image->width();
73 int frame_image_height = frame_image->height();
78 int red_x_shift_limit = round(frame_image_width * fmod(fabs(red_x_shift), 1.0));
80 int red_y_shift_limit = round(frame_image_height * fmod(fabs(red_y_shift), 1.0));
83 int green_x_shift_limit = round(frame_image_width * fmod(fabs(green_x_shift), 1.0));
85 int green_y_shift_limit = round(frame_image_height * fmod(fabs(green_y_shift), 1.0));
88 int blue_x_shift_limit = round(frame_image_width * fmod(fabs(blue_x_shift), 1.0));
90 int blue_y_shift_limit = round(frame_image_height * fmod(fabs(blue_y_shift), 1.0));
93 int alpha_x_shift_limit = round(frame_image_width * fmod(fabs(alpha_x_shift), 1.0));
95 int alpha_y_shift_limit = round(frame_image_height * fmod(fabs(alpha_y_shift), 1.0));
98 unsigned char *temp_image =
new unsigned char[frame_image_width * frame_image_height * 4]();
99 memcpy(temp_image, pixels,
sizeof(
char) * frame_image_width * frame_image_height * 4);
102 int starting_row_index = 0;
111 int red_starting_row_index = 0;
112 int green_starting_row_index = 0;
113 int blue_starting_row_index = 0;
114 int alpha_starting_row_index = 0;
116 int red_pixel_offset = 0;
117 int green_pixel_offset = 0;
118 int blue_pixel_offset = 0;
119 int alpha_pixel_offset = 0;
122 for (
int row = 0; row < frame_image_height; row++) {
123 for (
int col = 0; col < frame_image_width; col++) {
125 starting_row_index = row * frame_image_width * 4;
126 byte_index = starting_row_index + (col * 4);
127 red_starting_row_index = starting_row_index;
128 green_starting_row_index = starting_row_index;
129 blue_starting_row_index = starting_row_index;
130 alpha_starting_row_index = starting_row_index;
132 red_pixel_offset = 0;
133 green_pixel_offset = 0;
134 blue_pixel_offset = 0;
135 alpha_pixel_offset = 0;
138 R = temp_image[byte_index];
139 G = temp_image[byte_index + 1];
140 B = temp_image[byte_index + 2];
141 A = temp_image[byte_index + 3];
144 if (red_x_shift > 0.0)
145 red_pixel_offset = (col + red_x_shift_limit) % frame_image_width;
146 if (red_x_shift < 0.0)
147 red_pixel_offset = (frame_image_width + col - red_x_shift_limit) % frame_image_width;
148 if (green_x_shift > 0.0)
149 green_pixel_offset = (col + green_x_shift_limit) % frame_image_width;
150 if (green_x_shift < 0.0)
151 green_pixel_offset = (frame_image_width + col - green_x_shift_limit) % frame_image_width;
152 if (blue_x_shift > 0.0)
153 blue_pixel_offset = (col + blue_x_shift_limit) % frame_image_width;
154 if (blue_x_shift < 0.0)
155 blue_pixel_offset = (frame_image_width + col - blue_x_shift_limit) % frame_image_width;
156 if (alpha_x_shift > 0.0)
157 alpha_pixel_offset = (col + alpha_x_shift_limit) % frame_image_width;
158 if (alpha_x_shift < 0.0)
159 alpha_pixel_offset = (frame_image_width + col - alpha_x_shift_limit) % frame_image_width;
162 if (red_y_shift > 0.0)
163 red_starting_row_index = ((row + red_y_shift_limit) % frame_image_height) * frame_image_width * 4;
164 if (red_y_shift < 0.0)
165 red_starting_row_index = ((frame_image_height + row - red_y_shift_limit) % frame_image_height) * frame_image_width * 4;
166 if (green_y_shift > 0.0)
167 green_starting_row_index = ((row + green_y_shift_limit) % frame_image_height) * frame_image_width * 4;
168 if (green_y_shift < 0.0)
169 green_starting_row_index = ((frame_image_height + row - green_y_shift_limit) % frame_image_height) * frame_image_width * 4;
170 if (blue_y_shift > 0.0)
171 blue_starting_row_index = ((row + blue_y_shift_limit) % frame_image_height) * frame_image_width * 4;
172 if (blue_y_shift < 0.0)
173 blue_starting_row_index = ((frame_image_height + row - blue_y_shift_limit) % frame_image_height) * frame_image_width * 4;
174 if (alpha_y_shift > 0.0)
175 alpha_starting_row_index = ((row + alpha_y_shift_limit) % frame_image_height) * frame_image_width * 4;
176 if (alpha_y_shift < 0.0)
177 alpha_starting_row_index = ((frame_image_height + row - alpha_y_shift_limit) % frame_image_height) * frame_image_width * 4;
180 pixels[red_starting_row_index + 0 + (red_pixel_offset * 4)] = R;
181 pixels[green_starting_row_index + 1 + (green_pixel_offset * 4)] = G;
182 pixels[blue_starting_row_index + 2 + (blue_pixel_offset * 4)] = B;
183 pixels[alpha_starting_row_index + 3 + (alpha_pixel_offset * 4)] = A;
230 catch (
const std::exception& e)
233 throw InvalidJSON(
"JSON is invalid (missing keys or invalid data types)");
244 if (!root[
"red_x"].isNull())
246 if (!root[
"red_y"].isNull())
248 if (!root[
"green_x"].isNull())
250 if (!root[
"green_y"].isNull())
252 if (!root[
"blue_x"].isNull())
254 if (!root[
"blue_y"].isNull())
256 if (!root[
"alpha_x"].isNull())
258 if (!root[
"alpha_y"].isNull())
267 root[
"id"] =
add_property_json(
"ID", 0.0,
"string",
Id(), NULL, -1, -1,
true, requested_frame);
268 root[
"position"] =
add_property_json(
"Position",
Position(),
"float",
"", NULL, 0, 1000 * 60 * 30,
false, requested_frame);
270 root[
"start"] =
add_property_json(
"Start",
Start(),
"float",
"", NULL, 0, 1000 * 60 * 30,
false, requested_frame);
271 root[
"end"] =
add_property_json(
"End",
End(),
"float",
"", NULL, 0, 1000 * 60 * 30,
false, requested_frame);
272 root[
"duration"] =
add_property_json(
"Duration",
Duration(),
"float",
"", NULL, 0, 1000 * 60 * 30,
true, requested_frame);
285 return root.toStyledString();