forked from enlightenment/efl
evas: change TGV internal encoding to account for GPU needs of duplicated border.
With OpenGL, the border of a texture are not "well" defined. So interpolation at the border can result in weird/bad looking texture border. To avoid that we do duplicate the border in all direction at the time of the texture upload. But with ETC1 it is not possible as the border are grouped with 15 others pixels. It needs to be done at saving time. So internally we do have an image that would be of size width + 2 pixels and height + 2 pixels.
This commit is contained in:
parent
d1581f8ca9
commit
2fd69743f9
|
@ -28,6 +28,7 @@ evas_image_save_file_tgv(RGBA_Image *im,
|
|||
unsigned int x, y;
|
||||
unsigned int compress_length;
|
||||
unsigned int block_count;
|
||||
unsigned int real_x, real_y;
|
||||
|
||||
if (!im || !im->image.data || !file)
|
||||
return 0;
|
||||
|
@ -86,63 +87,104 @@ evas_image_save_file_tgv(RGBA_Image *im,
|
|||
}
|
||||
|
||||
// Write block
|
||||
for (y = 0; y < im->cache_entry.h; y += block)
|
||||
for (x = 0; x < im->cache_entry.w; x += block)
|
||||
{
|
||||
unsigned int i, j;
|
||||
int wlen;
|
||||
char *offset = buffer;
|
||||
for (y = 0; y < im->cache_entry.h + 2; y += block)
|
||||
{
|
||||
real_y = y > 0 ? y - 1 : 0;
|
||||
|
||||
for (i = 0; i < block; i += 4)
|
||||
for (j = 0; j < block; j += 4)
|
||||
{
|
||||
unsigned char todo[64] = { 0 };
|
||||
int k, kmax, lmax;
|
||||
for (x = 0; x < im->cache_entry.w + 2; x += block)
|
||||
{
|
||||
unsigned int i, j;
|
||||
unsigned char duplicate_w[2], duplicate_h[2];
|
||||
int wlen;
|
||||
char *offset = buffer;
|
||||
|
||||
kmax = y + i + 4 < im->cache_entry.h ?
|
||||
4 : im->cache_entry.h - y - i - 1;
|
||||
lmax = x + j + 4 < im->cache_entry.w ?
|
||||
4 : im->cache_entry.w - x - j - 1;
|
||||
real_x = x > 0 ? x - 1 : 0;
|
||||
|
||||
if (lmax > 0)
|
||||
{
|
||||
for (k = 0; k < kmax; k++)
|
||||
memcpy(&todo[k * 16],
|
||||
&data[(y + i + k) * im->cache_entry.w + x + j],
|
||||
4 * lmax);
|
||||
}
|
||||
for (i = 0; i < block; i += 4)
|
||||
{
|
||||
unsigned char block_h;
|
||||
int kmax;
|
||||
|
||||
rg_etc1_pack_block(offset, (unsigned int*) todo, ¶m);
|
||||
offset += 8;
|
||||
}
|
||||
duplicate_h[0] = !!((real_y + i) == 0);
|
||||
duplicate_h[1] = !!((real_y + i + (4 - duplicate_h[0])) >= im->cache_entry.h);
|
||||
block_h = 4 - duplicate_h[0] - duplicate_h[1];
|
||||
|
||||
if (compress)
|
||||
{
|
||||
wlen = LZ4_compress(buffer, comp, block_count * 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
comp = buffer;
|
||||
wlen = block_count * 8;
|
||||
}
|
||||
kmax = real_y + i + block_h < im->cache_entry.h ?
|
||||
block_h : im->cache_entry.h - real_y - i - 1;
|
||||
|
||||
if (wlen > 0)
|
||||
{
|
||||
unsigned int blen = wlen;
|
||||
for (j = 0; j < block; j += 4)
|
||||
{
|
||||
unsigned char todo[64] = { 0 };
|
||||
unsigned char block_w;
|
||||
int block_length;
|
||||
int k, lmax;
|
||||
|
||||
while (blen)
|
||||
{
|
||||
unsigned char plen;
|
||||
duplicate_w[0] = !!((real_x + j) == 0);
|
||||
duplicate_w[1] = !!(((real_x + j + (4 - duplicate_w[0]))) >= im->cache_entry.w);
|
||||
block_w = 4 - duplicate_w[0] - duplicate_w[1];
|
||||
|
||||
plen = blen & 0x7F;
|
||||
blen = blen >> 7;
|
||||
lmax = real_x + j + block_w < im->cache_entry.w ?
|
||||
block_w : im->cache_entry.w - real_x - j - 1;
|
||||
block_length = real_x + j + 4 < im->cache_entry.w ?
|
||||
4 : im->cache_entry.w - real_x - j - 1;
|
||||
|
||||
if (blen) plen = 0x80 | plen;
|
||||
fwrite(&plen, 1, 1, f);
|
||||
}
|
||||
fwrite(comp, wlen, 1, f);
|
||||
}
|
||||
}
|
||||
if (lmax > 0)
|
||||
{
|
||||
for (k = duplicate_h[0]; k < kmax; k++)
|
||||
memcpy(&todo[k * 16 + duplicate_w[0] * 4],
|
||||
&data[(real_y + i + k) * im->cache_entry.w + real_x + j],
|
||||
4 * lmax);
|
||||
}
|
||||
|
||||
if (duplicate_h[0] && block_length > 0) // Duplicate first line
|
||||
memcpy(&todo[0], &data[(real_y + i) * im->cache_entry.w + real_x + j], block_length);
|
||||
if (duplicate_h[1] && block_length > 0 && kmax > 0) // Duplicate last line
|
||||
memcpy(&todo[kmax * 16], &data[(real_y + i + kmax) * im->cache_entry.w + real_x + j], block_length);
|
||||
if (duplicate_w[0]) // Duplicate first row
|
||||
{
|
||||
for (k = 0; k < kmax; k++)
|
||||
memcpy(&todo[k * 16], &data[(real_y + i + k) * im->cache_entry.w + real_x + j], 4); // Copy a pixel at a time
|
||||
}
|
||||
if (duplicate_w[1] && lmax >= 0) // Duplicate last row
|
||||
{
|
||||
for (k = 0; k < kmax; k++)
|
||||
memcpy(&todo[k * 16 + (duplicate_w[0] + lmax) * 4],
|
||||
&data[(real_y + i + k) * im->cache_entry.w + real_x + j + lmax], 4); // Copy a pixel at a time
|
||||
}
|
||||
|
||||
rg_etc1_pack_block(offset, (unsigned int*) todo, ¶m);
|
||||
offset += 8;
|
||||
}
|
||||
}
|
||||
|
||||
if (compress)
|
||||
{
|
||||
wlen = LZ4_compress(buffer, comp, block_count * 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
comp = buffer;
|
||||
wlen = block_count * 8;
|
||||
}
|
||||
|
||||
if (wlen > 0)
|
||||
{
|
||||
unsigned int blen = wlen;
|
||||
|
||||
while (blen)
|
||||
{
|
||||
unsigned char plen;
|
||||
|
||||
plen = blen & 0x7F;
|
||||
blen = blen >> 7;
|
||||
|
||||
if (blen) plen = 0x80 | plen;
|
||||
fwrite(&plen, 1, 1, f);
|
||||
}
|
||||
fwrite(comp, wlen, 1, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
return 1;
|
||||
|
|
Loading…
Reference in New Issue