diff --git a/Makefile b/Makefile index eed1a54..10c1a11 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ SRC = rotation.cpp \ HEADERS = image.h \ pnm.h OBJS = $(patsubst %.cpp,%.o,$(SRC)) -IMG = img/lena_1024.pgm +IMG = img/lena_3000.pgm all: $(OBJS) $(CXX) $(CXXFLAGS) $(LFLAGS) $(OBJS) -o $(BUILD_DIR)/rotation diff --git a/rotation.cpp b/rotation.cpp index 26e259c..3b5214e 100644 --- a/rotation.cpp +++ b/rotation.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -181,33 +182,17 @@ int get_iteration(int distance, int upper_bound, int step) uint16_t* generate_padding_table(Image const& rotated, Point src_rotated_origin, Point const& qdx, Point const& qdy, - int src_qwidth, int src_qheight) + int src_qwidth, int src_qheight, + int q_pos) { uint16_t* padding_table = new uint16_t[rotated.height]; - // We suppose the image is square. - if (qdx.x == 0 || qdx.y == 0) - { - memset(padding_table, 0, sizeof (uint16_t) * rotated.height); - return padding_table; - } for (unsigned int i = 0; i < rotated.height; ++i) { - int y_range = get_iteration(src_rotated_origin.y, src_qheight, qdx.y); - if (y_range < 0) - { - cout << "Negative Y range" << endl; - abort(); - } + int x_range = get_iteration(src_rotated_origin.x, src_qwidth - q_pos, qdx.x); + int y_range = get_iteration(src_rotated_origin.y, src_qheight - q_pos, qdx.y); - int x_range = get_iteration(src_rotated_origin.x, src_qwidth, qdx.x); - if (x_range < 0) - { - cout << "Negative X range" << endl; - abort(); - } - - padding_table[i] = max(x_range, y_range); + padding_table[i] = max(max(x_range, y_range), 0); Point border(src_rotated_origin.x + padding_table[i] * qdx.x, src_rotated_origin.y + padding_table[i] * qdx.y); @@ -255,40 +240,27 @@ uint16_t* generate_padding_table(Image const& rotated, uint16_t* generate_padding_table_back(Image const& rotated, Point src_rotated_origin, - Point const& qdx, - Point const& qdy, - int src_qwidth, - int src_qheight, + Point const& qdx, Point const& qdy, + int src_qwidth, int src_qheight, + int q_pos, uint16_t const* front_padding) { uint16_t* padding_table = new uint16_t[rotated.height]; - // We suppose the image is square. - if (qdx.x == 0 || qdx.y == 0) - { - memset(padding_table, 0, sizeof (uint16_t) * rotated.height); - return padding_table; - } src_rotated_origin.x += (rotated.width - 1) * qdx.x; src_rotated_origin.y += (rotated.width - 1) * qdx.y; - for (unsigned int i = 0; i < rotated.height; ++i) + // This is actually a border + padding_table[0] = rotated.width - front_padding[0]; + src_rotated_origin += qdy; + padding_table[rotated.height - 1] = rotated.width - front_padding[rotated.height - 1]; + + for (unsigned int i = 1; i < rotated.height - 1; ++i) { - int y_range = get_iteration(src_rotated_origin.y, src_qheight, -qdx.y); - if (y_range < 0) - { - cout << "Negative back Y range at line " << i << endl; - abort(); - } + int x_range = get_iteration(src_rotated_origin.x, src_qwidth - q_pos, -qdx.x); + int y_range = get_iteration(src_rotated_origin.y, src_qheight - q_pos, -qdx.y); - int x_range = get_iteration(src_rotated_origin.x, src_qwidth, -qdx.x); - if (x_range < 0) - { - cout << "Negative back X range at line " << i << endl; - abort(); - } - - padding_table[i] = max(x_range, y_range); + padding_table[i] = max(max(x_range, y_range), 0); padding_table[i] = min((int) padding_table[i], (int) rotated.width - front_padding[i]); src_rotated_origin += qdy; @@ -554,23 +526,25 @@ Image* rotate(Image const& src, double angle) Point src_rotated_origin(rot_origin_in_src.x * q_pos, rot_origin_in_src.y * q_pos); // Padding - uint16_t* padding_table = generate_padding_table(*rotated, src_rotated_origin, - qdx, qdy, - src_qwidth, src_qheight); - uint16_t* back_padding_table = generate_padding_table_back(*rotated, src_rotated_origin, - qdx, qdy, - src_qwidth, src_qheight, - padding_table); - uint16_t* front_border = generate_border_table(padding_table, back_padding_table, *rotated); - uint16_t* back_border = generate_border_table_back(padding_table, front_border, back_padding_table, *rotated); + unique_ptr padding_table(generate_padding_table(*rotated, src_rotated_origin, + qdx, qdy, + src_qwidth, src_qheight, + q_pos)); + unique_ptr back_padding_table(generate_padding_table_back(*rotated, src_rotated_origin, + qdx, qdy, + src_qwidth, src_qheight, + q_pos, + padding_table.get())); +// uint16_t* front_border = generate_border_table(padding_table, back_padding_table, *rotated); +// uint16_t* back_border = generate_border_table_back(padding_table, front_border, back_padding_table, *rotated); for (int y = 0; y < height; ++y) { // TODO: compact these structure to increase locality int const left_padding = padding_table[y]; - int const left_border = front_border[y]; - int const right_border = back_border[y]; + int const left_border = 0; + int const right_border = 0; int const right_padding = back_padding_table[y]; int const core_pixels = width - left_padding - left_border - right_border - right_padding; @@ -595,7 +569,7 @@ Image* rotate(Image const& src, double angle) // Left padding // TODO: set to background value - memset(buffer + buffer_index, 50, left_padding * sizeof (pvalue_t)); + memset(buffer + buffer_index, 0, left_padding * sizeof (pvalue_t)); buffer_index += left_padding; // Border @@ -610,30 +584,7 @@ Image* rotate(Image const& src, double angle) // Body for (int x = 0; x < core_pixels; ++x, ++buffer_index) { - if (src_rotated_point.x < 0 || src_rotated_point.y < 0 - || src_rotated_point.x >= src_qwidth - q_pos || src_rotated_point.y >= src_qheight - q_pos) - { -// LOG << "Out-of-bounds point!" << endl; -// cout << " x: " << x << endl; -// cout << " src_rotated_point: " << src_rotated_point << endl; -// cout << " qdx: " << qdx << endl; -// cout << " q_pos: " << q_pos << endl; -// cout << " rotated point: (" << x + left_padding + left_border << ", " << y << ")" << endl; -// cout << " src point: (" << (src_rotated_point.x >> q_pos_pow) << ", " << (src_rotated_point.y >> q_pos_pow) << ")" << endl; -// cout << " src point: (" << (src_rotated_point.x / q_pos) << ", " << (src_rotated_point.y / q_pos) << ")" << endl; -// cout << " width: " << width << endl; -// cout << " left padding: " << left_padding << endl; -// cout << " left border: " << left_border << endl; -// cout << " core pixels: " << core_pixels << endl; -// cout << " right border: " << right_border << endl; -// cout << " right padding: " << right_padding << endl; - buffer[buffer_index] = 255; - } - else - { - rotate_pixel(src, src_rotated_point, buffer, buffer_index, q_pos_pow); - } - + rotate_pixel(src, src_rotated_point, buffer, buffer_index, q_pos_pow); src_rotated_point += qdx; } @@ -646,12 +597,11 @@ Image* rotate(Image const& src, double angle) // Right padding // TODO: set to background value - memset(buffer + buffer_index, 100, right_padding * sizeof (pvalue_t)); + memset(buffer + buffer_index, 0, right_padding * sizeof (pvalue_t)); buffer_index += right_padding; src_rotated_origin += qdy; } -// cout << endl; return rotated; } @@ -874,7 +824,7 @@ int main(int argc, char* argv[]) double const step = 5; bool save_output_img = true; - bool print_each_run = true; + bool print_each_run = false; // No tile Image img(argv[1]);