Return image pointer for rotate().

master
Fabien Freling 2014-07-03 23:51:41 +02:00
parent 8d096ee2ce
commit 9e8d79d384
1 changed files with 34 additions and 29 deletions

View File

@ -564,30 +564,30 @@ void rotate_pixel(Image const& src, Image& rotated,
rotated.buffer[rot_index + 2] = top_left[1];
}
Image rotate(Image const& src, double angle)
Image* rotate(Image const& src, double angle)
{
double const rotation = (angle / 180.0f) * M_PI;
unsigned int w = 0;
unsigned int h = 0;
compute_output_size(src, rotation, w, h);
Image rotated(w, h);
Image* rotated = new Image(w, h);
// corner points in rotated image
// TODO: add one ligne for smooth border
DPoint const tl_grid = get_mapped_point(src, Point(0, 0), rotation);
Point const tl = convert_img_coord(rotated, tl_grid);
Point const tl = convert_img_coord(*rotated, tl_grid);
DPoint const tr_grid = get_mapped_point(src, Point(src.width - 1, 0), rotation);
Point const tr = convert_img_coord(rotated, tr_grid);
Point const tr = convert_img_coord(*rotated, tr_grid);
DPoint const bl_grid = get_mapped_point(src, Point(0, src.height - 1), rotation);
Point const bl = convert_img_coord(rotated, bl_grid);
Point const bl = convert_img_coord(*rotated, bl_grid);
// corner points in source image
DPoint src_tl = get_mapped_point(rotated, tl, -rotation);
DPoint src_tl = get_mapped_point(*rotated, tl, -rotation);
src_tl = convert_img_coord_precision(src, src_tl);
DPoint src_origin = get_mapped_point(rotated, Point(0, 0), -rotation);
DPoint src_delta_x = get_mapped_point(rotated, Point(1, 0), -rotation);
DPoint src_delta_y = get_mapped_point(rotated, Point(0, 1), -rotation);
DPoint const src_origin = get_mapped_point(*rotated, Point(0, 0), -rotation);
DPoint src_delta_x = get_mapped_point(*rotated, Point(1, 0), -rotation);
DPoint src_delta_y = get_mapped_point(*rotated, Point(0, 1), -rotation);
src_delta_x.x = src_delta_x.x - src_origin.x;
src_delta_x.y = src_delta_x.y - src_origin.y;
@ -613,7 +613,7 @@ Image rotate(Image const& src, double angle)
DPoint bresenham((tr.x - tl.x) / (float) line_nb_steps, (tr.y - tl.y) / (float) line_nb_steps);
unsigned int const src_limit = src.width * src.height * 3;
unsigned int const rot_limit = rotated.width * rotated.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)
{
@ -630,7 +630,7 @@ Image rotate(Image const& src, double angle)
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);
rotate_pixel(src, *rotated, src_rotated_point, rot_point, src_limit, rot_limit);
if (previous.x != rot_point.x && previous.y != rot_point.y)
{
@ -641,7 +641,7 @@ Image rotate(Image const& src, double angle)
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);
rotate_pixel(src, *rotated, src_rotated_point, rot_point, src_limit, rot_limit);
rot_point.y = tmp_y;
}
@ -715,17 +715,18 @@ void rotate_pixel(TiledImage<W, H> const& src, TiledImage<W, H>& rotated,
}
template<unsigned int W, unsigned int H>
TiledImage<W, H> rotate(TiledImage<W, H> const& src, double angle)
TiledImage<W, H>*
rotate(TiledImage<W, H> const& src, double angle)
{
double const rotation = (angle / 180.0f) * M_PI;
unsigned int w = 0;
unsigned int h = 0;
compute_output_size(src, rotation, w, h);
TiledImage<W, H> rotated(w, h);
auto rotated = new TiledImage<W, H>(w, h);
DPoint src_origin = get_mapped_point(rotated, Point(0, 0), -rotation);
DPoint src_delta_x = get_mapped_point(rotated, Point(1, 0), -rotation);
DPoint src_delta_y = get_mapped_point(rotated, Point(0, 1), -rotation);
DPoint src_origin = get_mapped_point(*rotated, Point(0, 0), -rotation);
DPoint src_delta_x = get_mapped_point(*rotated, Point(1, 0), -rotation);
DPoint src_delta_y = get_mapped_point(*rotated, Point(0, 1), -rotation);
src_delta_x.x = src_delta_x.x - src_origin.x;
src_delta_x.y = src_delta_x.y - src_origin.y;
@ -736,14 +737,14 @@ TiledImage<W, H> rotate(TiledImage<W, H> const& src, double angle)
round_if_very_small(src_delta_y.x);
round_if_very_small(src_delta_y.y);
DPoint const rot_origin_in_src_grid = get_mapped_point(rotated, Point(0, 0), -rotation);
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);
for (unsigned int y = 0; y < rotated.nb_row_tile; ++y)
for (unsigned int y = 0; y < rotated->nb_row_tile; ++y)
{
for (unsigned int x = 0; x < rotated.nb_col_tile; ++x)
for (unsigned int x = 0; x < rotated->nb_col_tile; ++x)
{
unsigned int const rot_tile_index = y * rotated.nb_col_tile + x;
unsigned int const rot_tile_index = y * rotated->nb_col_tile + x;
for (unsigned int j = 0; j < H; ++j)
{
@ -761,7 +762,7 @@ TiledImage<W, H> rotate(TiledImage<W, H> const& src, double angle)
|| src_rotated_point.y < 0 || src_rotated_point.y > src.height)
continue;
rotate_pixel(src, rotated,
rotate_pixel(src, *rotated,
src_rotated_point,
rot_tile_index, rot_index);
@ -885,26 +886,28 @@ bool check_trigo()
bool check_90(string const& path)
{
Image const src(path);
Image const rotated = rotate(src, 90);
Image const* rotated = rotate(src, 90);
for (unsigned int y = 0; y < rotated.height; ++y)
for (unsigned int y = 0; y < rotated->height; ++y)
{
for (unsigned int x = 0; x < rotated.width; ++x)
for (unsigned int x = 0; x < rotated->width; ++x)
{
unsigned rot_index = (y * rotated.width + x) * 3;
unsigned rot_index = (y * rotated->width + x) * 3;
unsigned src_index = (x * src.width + (src.width - 1 - y)) * 3;
if (memcmp(&rotated.buffer[rot_index], &src.buffer[src_index], 3 * sizeof (uint8_t)) != 0)
if (memcmp(&rotated->buffer[rot_index], &src.buffer[src_index], 3 * sizeof (uint8_t)) != 0)
{
Point r(x, y);
Point s((src.width - 1 - y), x);
cerr << __LINE__ << " | R: " << r << " != S:" << s << endl;
cerr << "R dim: " << rotated.width << " x " << rotated.height << endl;
cerr << "R dim: " << rotated->width << " x " << rotated->height << endl;
cerr << "S dim: " << src.width << " x " << src.height << endl;
return false;
}
}
}
delete rotated;
return true;
}
@ -961,7 +964,7 @@ int main(int argc, char* argv[])
{
// No tile
auto const before = chrono::high_resolution_clock::now();
Image const rotated = rotate(img, rotation);
Image* const rotated = rotate(img, rotation);
auto const after = chrono::high_resolution_clock::now();
auto const duration_ms = std::chrono::duration_cast<std::chrono::milliseconds>(after - before);
@ -978,6 +981,8 @@ int main(int argc, char* argv[])
rotated->save(get_save_path("rotated", rotation));
rotated_tiled->save(get_save_path("rotated_tiled", rotation));
delete rotated;
delete rotated_tiled;
}
return 0;