Allocate tiles as a unified buffer.

This commit is contained in:
Fabien Freling 2014-07-09 07:50:09 +02:00
parent edb9ef7dd8
commit eb5bae42c3
2 changed files with 36 additions and 30 deletions

View file

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

View file

@ -246,7 +246,7 @@ struct Image {
template<unsigned int W, unsigned int H>
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<unsigned int W, unsigned int H>
void rotate_pixel(TiledImage<W, H> 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<W, H> 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<unsigned int W, unsigned int H>
@ -796,8 +804,7 @@ rotate(TiledImage<W, H> 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<W, H> 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;
}
}
}