Update padding and deactivate borders.
Borders are merged with padding for now.
This commit is contained in:
parent
4f46d32b9e
commit
242813ed41
2
Makefile
2
Makefile
|
@ -9,7 +9,7 @@ SRC = rotation.cpp \
|
||||||
HEADERS = image.h \
|
HEADERS = image.h \
|
||||||
pnm.h
|
pnm.h
|
||||||
OBJS = $(patsubst %.cpp,%.o,$(SRC))
|
OBJS = $(patsubst %.cpp,%.o,$(SRC))
|
||||||
IMG = img/lena_1024.pgm
|
IMG = img/lena_3000.pgm
|
||||||
|
|
||||||
all: $(OBJS)
|
all: $(OBJS)
|
||||||
$(CXX) $(CXXFLAGS) $(LFLAGS) $(OBJS) -o $(BUILD_DIR)/rotation
|
$(CXX) $(CXXFLAGS) $(LFLAGS) $(OBJS) -o $(BUILD_DIR)/rotation
|
||||||
|
|
120
rotation.cpp
120
rotation.cpp
|
@ -8,6 +8,7 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <xmmintrin.h>
|
#include <xmmintrin.h>
|
||||||
#include <emmintrin.h>
|
#include <emmintrin.h>
|
||||||
|
@ -181,33 +182,17 @@ int get_iteration(int distance, int upper_bound, int step)
|
||||||
uint16_t* generate_padding_table(Image const& rotated,
|
uint16_t* generate_padding_table(Image const& rotated,
|
||||||
Point src_rotated_origin,
|
Point src_rotated_origin,
|
||||||
Point const& qdx, Point const& qdy,
|
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];
|
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)
|
for (unsigned int i = 0; i < rotated.height; ++i)
|
||||||
{
|
{
|
||||||
int y_range = get_iteration(src_rotated_origin.y, src_qheight, qdx.y);
|
int x_range = get_iteration(src_rotated_origin.x, src_qwidth - q_pos, qdx.x);
|
||||||
if (y_range < 0)
|
int y_range = get_iteration(src_rotated_origin.y, src_qheight - q_pos, qdx.y);
|
||||||
{
|
|
||||||
cout << "Negative Y range" << endl;
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
int x_range = get_iteration(src_rotated_origin.x, src_qwidth, qdx.x);
|
padding_table[i] = max(max(x_range, y_range), 0);
|
||||||
if (x_range < 0)
|
|
||||||
{
|
|
||||||
cout << "Negative X range" << endl;
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
padding_table[i] = max(x_range, y_range);
|
|
||||||
|
|
||||||
Point border(src_rotated_origin.x + padding_table[i] * qdx.x,
|
Point border(src_rotated_origin.x + padding_table[i] * qdx.x,
|
||||||
src_rotated_origin.y + padding_table[i] * qdx.y);
|
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,
|
uint16_t* generate_padding_table_back(Image const& rotated,
|
||||||
Point src_rotated_origin,
|
Point src_rotated_origin,
|
||||||
Point const& qdx,
|
Point const& qdx, Point const& qdy,
|
||||||
Point const& qdy,
|
int src_qwidth, int src_qheight,
|
||||||
int src_qwidth,
|
int q_pos,
|
||||||
int src_qheight,
|
|
||||||
uint16_t const* front_padding)
|
uint16_t const* front_padding)
|
||||||
{
|
{
|
||||||
uint16_t* padding_table = new uint16_t[rotated.height];
|
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.x += (rotated.width - 1) * qdx.x;
|
||||||
src_rotated_origin.y += (rotated.width - 1) * qdx.y;
|
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);
|
int x_range = get_iteration(src_rotated_origin.x, src_qwidth - q_pos, -qdx.x);
|
||||||
if (y_range < 0)
|
int y_range = get_iteration(src_rotated_origin.y, src_qheight - q_pos, -qdx.y);
|
||||||
{
|
|
||||||
cout << "Negative back Y range at line " << i << endl;
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
int x_range = get_iteration(src_rotated_origin.x, src_qwidth, -qdx.x);
|
padding_table[i] = max(max(x_range, y_range), 0);
|
||||||
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] = min((int) padding_table[i], (int) rotated.width - front_padding[i]);
|
padding_table[i] = min((int) padding_table[i], (int) rotated.width - front_padding[i]);
|
||||||
|
|
||||||
src_rotated_origin += qdy;
|
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,
|
Point src_rotated_origin(rot_origin_in_src.x * q_pos,
|
||||||
rot_origin_in_src.y * q_pos);
|
rot_origin_in_src.y * q_pos);
|
||||||
// Padding
|
// Padding
|
||||||
uint16_t* padding_table = generate_padding_table(*rotated, src_rotated_origin,
|
unique_ptr<uint16_t[]> padding_table(generate_padding_table(*rotated, src_rotated_origin,
|
||||||
qdx, qdy,
|
qdx, qdy,
|
||||||
src_qwidth, src_qheight);
|
src_qwidth, src_qheight,
|
||||||
uint16_t* back_padding_table = generate_padding_table_back(*rotated, src_rotated_origin,
|
q_pos));
|
||||||
qdx, qdy,
|
unique_ptr<uint16_t[]> back_padding_table(generate_padding_table_back(*rotated, src_rotated_origin,
|
||||||
src_qwidth, src_qheight,
|
qdx, qdy,
|
||||||
padding_table);
|
src_qwidth, src_qheight,
|
||||||
uint16_t* front_border = generate_border_table(padding_table, back_padding_table, *rotated);
|
q_pos,
|
||||||
uint16_t* back_border = generate_border_table_back(padding_table, front_border, back_padding_table, *rotated);
|
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)
|
for (int y = 0; y < height; ++y)
|
||||||
{
|
{
|
||||||
|
|
||||||
// TODO: compact these structure to increase locality
|
// TODO: compact these structure to increase locality
|
||||||
int const left_padding = padding_table[y];
|
int const left_padding = padding_table[y];
|
||||||
int const left_border = front_border[y];
|
int const left_border = 0;
|
||||||
int const right_border = back_border[y];
|
int const right_border = 0;
|
||||||
int const right_padding = back_padding_table[y];
|
int const right_padding = back_padding_table[y];
|
||||||
int const core_pixels = width - left_padding - left_border - right_border - right_padding;
|
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
|
// Left padding
|
||||||
// TODO: set to background value
|
// 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;
|
buffer_index += left_padding;
|
||||||
|
|
||||||
// Border
|
// Border
|
||||||
|
@ -610,30 +584,7 @@ Image* rotate(Image const& src, double angle)
|
||||||
// Body
|
// Body
|
||||||
for (int x = 0; x < core_pixels; ++x, ++buffer_index)
|
for (int x = 0; x < core_pixels; ++x, ++buffer_index)
|
||||||
{
|
{
|
||||||
if (src_rotated_point.x < 0 || src_rotated_point.y < 0
|
rotate_pixel(src, src_rotated_point, buffer, buffer_index, q_pos_pow);
|
||||||
|| 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
src_rotated_point += qdx;
|
src_rotated_point += qdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -646,12 +597,11 @@ Image* rotate(Image const& src, double angle)
|
||||||
|
|
||||||
// Right padding
|
// Right padding
|
||||||
// TODO: set to background value
|
// 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;
|
buffer_index += right_padding;
|
||||||
|
|
||||||
src_rotated_origin += qdy;
|
src_rotated_origin += qdy;
|
||||||
}
|
}
|
||||||
// cout << endl;
|
|
||||||
|
|
||||||
return rotated;
|
return rotated;
|
||||||
}
|
}
|
||||||
|
@ -874,7 +824,7 @@ int main(int argc, char* argv[])
|
||||||
|
|
||||||
double const step = 5;
|
double const step = 5;
|
||||||
bool save_output_img = true;
|
bool save_output_img = true;
|
||||||
bool print_each_run = true;
|
bool print_each_run = false;
|
||||||
|
|
||||||
// No tile
|
// No tile
|
||||||
Image img(argv[1]);
|
Image img(argv[1]);
|
||||||
|
|
Loading…
Reference in a new issue