Update padding and deactivate borders.

Borders are merged with padding for now.
master
Fabien Freling 2014-08-07 19:50:13 +02:00
parent 4f46d32b9e
commit 242813ed41
2 changed files with 36 additions and 86 deletions

View File

@ -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

View File

@ -8,6 +8,7 @@
#include <cstring>
#include <chrono>
#include <cstdlib>
#include <memory>
#include <xmmintrin.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,
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<uint16_t[]> padding_table(generate_padding_table(*rotated, src_rotated_origin,
qdx, qdy,
src_qwidth, src_qheight,
q_pos));
unique_ptr<uint16_t[]> 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]);