diff --git a/Makefile b/Makefile index 127aeb2..3206af0 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CXX = clang++ -CXXFLAGS = -std=c++11 -W -Wall -O3 -ffast-math #-Werror +CXXFLAGS = -std=c++11 -W -Wall -O3 -ffast-math -Werror -g BUILD_DIR=/tmp all: rotation.cpp diff --git a/rotation.cpp b/rotation.cpp index d641a3c..e7f6a87 100644 --- a/rotation.cpp +++ b/rotation.cpp @@ -534,12 +534,13 @@ DPoint get_mapped_point(Image const& src, Point const& p, double const rotation) } inline -void rotate_pixel(Image const& src, Image& rotated, - DPoint const& src_rotated_point, Point const& rot_point, - unsigned int const src_limit, unsigned int const rot_limit) +void rotate_pixel(Image const& src, /*uint8_t* rotated,*/ + DPoint const& src_rotated_point, /*Point const& rot_point,*/ + unsigned int const src_limit, unsigned int const rot_limit, + uint8_t* rotate_buffer, unsigned int rot_index) { unsigned int src_index = ((int) src_rotated_point.y * src.width + (int) src_rotated_point.x) * 3; - unsigned int rot_index = (rot_point.y * rotated.width + rot_point.x) * 3; +// unsigned int rot_index = (rot_point.y * rotated.width + rot_point.x) * 3; // Out-of-bounds check if (src_index >= src_limit @@ -563,7 +564,10 @@ void rotate_pixel(Image const& src, Image& rotated, // special case if we can directly map the src to the dest if (x_delta == 0 && y_delta == 0) { - memcpy(&rotated.buffer[rot_index], &src.buffer[src_index], 3 * sizeof (uint8_t)); + // memcpy(&rotated.buffer[rot_index], &src.buffer[src_index], 3 * sizeof (uint8_t)); + rotate_buffer[rot_index] = src.buffer[src_index]; + rotate_buffer[rot_index + 1] = src.buffer[src_index + 1]; + rotate_buffer[rot_index + 2] = src.buffer[src_index + 2]; return; } @@ -589,9 +593,9 @@ void rotate_pixel(Image const& src, Image& rotated, top_left = _mm_add_ps(top_left, bottom_left); // convert float values to uint8_t - rotated.buffer[rot_index] = top_left[3]; - rotated.buffer[rot_index + 1] = top_left[2]; - rotated.buffer[rot_index + 2] = top_left[1]; + rotate_buffer[rot_index] = top_left[3]; + rotate_buffer[rot_index + 1] = top_left[2]; + rotate_buffer[rot_index + 2] = top_left[1]; } Image* rotate(Image const& src, double angle) @@ -643,46 +647,72 @@ Image* rotate(Image const& src, double angle) unsigned int const src_limit = src.width * src.height * 3; unsigned int const rot_limit = rotated->width * rotated->height * 3; - for (int y_i = 0; y_i <= (int) origin_nb_steps; ++y_i) +// for (int y_i = 0; y_i <= (int) origin_nb_steps; ++y_i) +// { +// // first column origin +// Point const rot_origin(tl.x + y_i * rotated_step.x, tl.y + y_i * rotated_step.y); +// Point rot_point(rot_origin.x, rot_origin.y); +// DPoint rot_delta(0.0, 0.0); +// +// Point previous = rot_origin; +// +// for (int x_i = 0; x_i <= (int) line_nb_steps; ++x_i) +// { +// +// Point const delta(rot_point.x - tl.x, rot_point.y - tl.y); +// DPoint src_rotated_point(src_tl.x + delta.x * src_delta_x.x + delta.y * src_delta_y.x, +// src_tl.y + delta.x * src_delta_x.y + delta.y * src_delta_y.y); +// +// rotate_pixel(src, *rotated, src_rotated_point, rot_point, src_limit, rot_limit); +// +// if (previous.x != rot_point.x && previous.y != rot_point.y) +// { +// int y_slope = rot_point.y > previous.y ? 1 : -1; +// int tmp_y = rot_point.y; +// rot_point.y = previous.y; +// +// src_rotated_point.x -= y_slope * src_delta_y.x; +// src_rotated_point.y -= y_slope * src_delta_y.y; +// +// rotate_pixel(src, *rotated, src_rotated_point, rot_point, src_limit, rot_limit); +// +// rot_point.y = tmp_y; +// } +// +// previous = rot_point; +// +// rot_delta.x += bresenham.x; +// rot_point.x = rot_origin.x + (int) rot_delta.x; +// +// rot_delta.y += bresenham.y; +// rot_point.y = rot_origin.y + (int) rot_delta.y; +// } +// } + + DPoint const rot_origin_in_src_grid = get_mapped_point(*rotated, Point(0, 0), -rotation); + DPoint const rot_origin_in_src = convert_img_coord_precision(src, rot_origin_in_src_grid); + + unsigned int const buffer_size = rotated->width * 3; + uint8_t buffer[buffer_size]; + + for (unsigned int y = 0; y < rotated->height; ++y) { - // first column origin - Point const rot_origin(tl.x + y_i * rotated_step.x, tl.y + y_i * rotated_step.y); - Point rot_point(rot_origin.x, rot_origin.y); - DPoint rot_delta(0.0, 0.0); + memset(buffer, 0, buffer_size); + DPoint src_rotated_point(rot_origin_in_src.x + y * src_delta_y.x, + rot_origin_in_src.y + y * src_delta_y.y); - Point previous = rot_origin; - - for (int x_i = 0; x_i <= (int) line_nb_steps; ++x_i) + for (unsigned int x = 0; x < rotated->width; ++x) { - - Point const delta(rot_point.x - tl.x, rot_point.y - tl.y); - DPoint src_rotated_point(src_tl.x + delta.x * src_delta_x.x + delta.y * src_delta_y.x, - src_tl.y + delta.x * src_delta_x.y + delta.y * src_delta_y.y); - - rotate_pixel(src, *rotated, src_rotated_point, rot_point, src_limit, rot_limit); - - if (previous.x != rot_point.x && previous.y != rot_point.y) + if (src_rotated_point.x >= 0 && src_rotated_point.x < src.width + && src_rotated_point.y >= 0 && src_rotated_point.y < src.height) { - int y_slope = rot_point.y > previous.y ? 1 : -1; - int tmp_y = rot_point.y; - rot_point.y = previous.y; - - src_rotated_point.x -= y_slope * src_delta_y.x; - src_rotated_point.y -= y_slope * src_delta_y.y; - - rotate_pixel(src, *rotated, src_rotated_point, rot_point, src_limit, rot_limit); - - rot_point.y = tmp_y; + rotate_pixel(src, src_rotated_point, src_limit, rot_limit, buffer, x * 3); } - previous = rot_point; - - rot_delta.x += bresenham.x; - rot_point.x = rot_origin.x + (int) rot_delta.x; - - rot_delta.y += bresenham.y; - rot_point.y = rot_origin.y + (int) rot_delta.y; + src_rotated_point.x += src_delta_x.x; + src_rotated_point.y += src_delta_x.y; } + memcpy(rotated->buffer + buffer_size * y, buffer, buffer_size); } return rotated;