From eb5bae42c32e4e3c873fed4905c4ba618e53dcaa Mon Sep 17 00:00:00 2001 From: Fabien Freling Date: Wed, 9 Jul 2014 07:50:09 +0200 Subject: [PATCH] Allocate tiles as a unified buffer. --- TODO.md | 5 ++--- rotation.cpp | 61 +++++++++++++++++++++++++++++----------------------- 2 files changed, 36 insertions(+), 30 deletions(-) diff --git a/TODO.md b/TODO.md index c5e26ef..e6b08f3 100644 --- a/TODO.md +++ b/TODO.md @@ -14,11 +14,10 @@ [X] Cut image in tiles [ ] Overlap? [-] Rotate in one temp tile then copy/move it + [X] Align tiles in memory [-] Align memory -> no gain +[ ] RGBX format # Quality [X] Interpolate using SIMD, SSE (no big gain) [ ] Image borders - -# Bugs -[X] first tile on each row is missing diff --git a/rotation.cpp b/rotation.cpp index 5ee6839..c92ec1a 100644 --- a/rotation.cpp +++ b/rotation.cpp @@ -246,7 +246,7 @@ struct Image { template struct TiledImage : public Image { - uint8_t** tiles; + uint8_t* tiles; unsigned int static const tile_w = W; unsigned int static const tile_h = H; unsigned int static const tile_size = W * H; @@ -262,11 +262,6 @@ struct TiledImage : public Image { ~TiledImage() { - unsigned int const nb_tiles = nb_col_tile * nb_row_tile; - for (unsigned int i = 0; i < nb_tiles; ++i) - { - delete [] tiles[i]; - } delete [] tiles; } @@ -308,12 +303,30 @@ struct TiledImage : public Image { unsigned int const tile_width = tile_w * 3; unsigned int const tile_index = (y / tile_h) * nb_col_tile + (x / tile_w); - uint8_t* tile = tiles[tile_index]; + uint8_t* tile = tiles + tile_index * tile_size * 3; unsigned int const tile_j = y % tile_h; unsigned int const tile_i = x % tile_w; return tile + tile_j * tile_width + (tile_i * 3); } + uint8_t const* + get_tile(unsigned int index) const + { + if (index >= nb_col_tile * nb_row_tile) + return nullptr; + + return tiles + index * tile_size * 3; + } + + uint8_t* + get_tile(unsigned int index) + { + if (index >= nb_col_tile * nb_row_tile) + return nullptr; + + return tiles + index * tile_size * 3; + } + uint8_t const* access_pixel(unsigned int x, unsigned int y) const { @@ -323,8 +336,7 @@ struct TiledImage : public Image { unsigned int const tile_width = tile_w * 3; unsigned int const tile_index = (y / tile_h) * nb_col_tile + (x / tile_w); - //cout << "tile index: " << tile_index << endl; - uint8_t* tile = tiles[tile_index]; + const uint8_t* tile = this->get_tile(tile_index); unsigned int const tile_j = y % tile_h; unsigned int const tile_i = x % tile_w; return tile + tile_j * tile_width + (tile_i * 3); @@ -359,7 +371,7 @@ struct TiledImage : public Image { print_tile(unsigned int index) const { cout << "Tile[" << index << "]" << endl; - uint8_t const* tile = tiles[index]; + uint8_t const* tile = this->get_tile(index); unsigned int const tile_width = tile_w * 3; for (unsigned int j = 0; j < tile_h; ++j) { @@ -407,12 +419,8 @@ struct TiledImage : public Image { ++nb_row_tile; unsigned int const nb_tiles = nb_col_tile * nb_row_tile; - tiles = new uint8_t*[nb_tiles]; - for (unsigned int i = 0; i < nb_tiles; ++i) - { - tiles[i] = new uint8_t[tile_w * tile_h * 3]; - memset(tiles[i], 0, tile_w * tile_h * 3 * sizeof (uint8_t)); - } + tiles = new uint8_t[nb_tiles * tile_size * 3]; + memset(tiles, 0, nb_tiles * tile_size * 3 * sizeof (uint8_t)); } virtual bool read_body(std::ifstream& istr) @@ -731,7 +739,7 @@ Image* rotate(Image const& src, double angle) template void rotate_pixel(TiledImage const& src, Point const& src_rotated_point, - uint8_t* rot_tile, unsigned int rot_index) + uint8_t* rot_tile) { unsigned int const quantize = 8; @@ -753,12 +761,12 @@ void rotate_pixel(TiledImage const& src, unsigned int const inv_y = quantize - y_delta; // No SIMD - rot_tile[rot_index] = ((src_index_1[0] * inv_x + src_index_2[0] * x_delta) * inv_y - + (src_index_3[0] * inv_x + src_index_4[0] * x_delta) * y_delta) >> 6; - rot_tile[rot_index + 1] = ((src_index_1[1] * inv_x + src_index_2[1] * x_delta) * inv_y - + (src_index_3[1] * inv_x + src_index_4[1] * x_delta) * y_delta) >> 6; - rot_tile[rot_index + 2] = ((src_index_1[2] * inv_x + src_index_2[2] * x_delta) * inv_y - + (src_index_3[2] * inv_x + src_index_4[2] * x_delta) * y_delta) >> 6; + rot_tile[0] = ((src_index_1[0] * inv_x + src_index_2[0] * x_delta) * inv_y + + (src_index_3[0] * inv_x + src_index_4[0] * x_delta) * y_delta) >> 6; + rot_tile[1] = ((src_index_1[1] * inv_x + src_index_2[1] * x_delta) * inv_y + + (src_index_3[1] * inv_x + src_index_4[1] * x_delta) * y_delta) >> 6; + rot_tile[2] = ((src_index_1[2] * inv_x + src_index_2[2] * x_delta) * inv_y + + (src_index_3[2] * inv_x + src_index_4[2] * x_delta) * y_delta) >> 6; } template @@ -796,8 +804,7 @@ rotate(TiledImage const& src, double angle) for (unsigned int x = 0; x < rotated->nb_col_tile; ++x) { unsigned int const rot_tile_index = y * rotated->nb_col_tile + x; - uint8_t* tile = rotated->tiles[rot_tile_index]; - unsigned int rot_index = 0; + uint8_t* runner = rotated->get_tile(rot_tile_index); for (unsigned int j = 0; j < H; ++j) { @@ -814,10 +821,10 @@ rotate(TiledImage const& src, double angle) if (src_runner.x >= 0 && src_runner.x < src_qwidth && src_runner.y >= 0 && src_runner.y < src_qheight) { - rotate_pixel(src, src_runner, tile, rot_index); + rotate_pixel(src, src_runner, runner); } - rot_index += 3; + runner += 3; } } }