summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorFerenc Arn <tagcup@yahoo.com>2017-04-29 20:14:14 -0500
committerFerenc Arn <tagcup@yahoo.com>2017-05-18 16:57:53 -0500
commit3c175115ebf54bcf5f53ab7a2d4926c6773665db (patch)
treef303e830e07a5228f4d93ff866c3c53e2a226dd8 /core
parenta75623f436c215e107ede321afa08a1897552deb (diff)
Use libsquish to decompress DXT textures.
Diffstat (limited to 'core')
-rw-r--r--core/image.cpp329
-rw-r--r--core/image.h2
2 files changed, 4 insertions, 327 deletions
diff --git a/core/image.cpp b/core/image.cpp
index 85ca63be5e..316faf954e 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -1370,7 +1370,7 @@ Error Image::load(const String &p_path) {
return ImageLoader::load_image(p_path, this);
}
-Error Image::save_png(const String &p_path) {
+Error Image::save_png(const String &p_path) const {
if (save_png_func == NULL)
return ERR_UNAVAILABLE;
@@ -1391,337 +1391,14 @@ int Image::get_image_required_mipmaps(int p_width, int p_height, Format p_format
return mm;
}
-Error Image::_decompress_bc() {
-
- int wd = width, ht = height;
- if (wd % 4 != 0) {
- wd += 4 - (wd % 4);
- }
- if (ht % 4 != 0) {
- ht += 4 - (ht % 4);
- }
-
- int mm;
- int size = _get_dst_image_size(wd, ht, FORMAT_RGBA8, mm);
-
- PoolVector<uint8_t> newdata;
- newdata.resize(size);
-
- PoolVector<uint8_t>::Write w = newdata.write();
- PoolVector<uint8_t>::Read r = data.read();
-
- int rofs = 0;
- int wofs = 0;
-
- //print_line("width: "+itos(wd)+" height: "+itos(ht));
-
- for (int i = 0; i <= mm; i++) {
-
- switch (format) {
-
- case FORMAT_DXT1: {
-
- int len = (wd * ht) / 16;
- uint8_t *dst = &w[wofs];
-
- uint32_t ofs_table[16];
- for (int x = 0; x < 4; x++) {
-
- for (int y = 0; y < 4; y++) {
-
- ofs_table[15 - (y * 4 + (3 - x))] = (x + y * wd) * 4;
- }
- }
-
- for (int j = 0; j < len; j++) {
-
- const uint8_t *src = &r[rofs + j * 8];
- uint16_t col_a = src[1];
- col_a <<= 8;
- col_a |= src[0];
- uint16_t col_b = src[3];
- col_b <<= 8;
- col_b |= src[2];
-
- uint8_t table[4][4] = {
- { uint8_t((col_a >> 11) << 3), uint8_t(((col_a >> 5) & 0x3f) << 2), uint8_t(((col_a)&0x1f) << 3), 255 },
- { uint8_t((col_b >> 11) << 3), uint8_t(((col_b >> 5) & 0x3f) << 2), uint8_t(((col_b)&0x1f) << 3), 255 },
- { 0, 0, 0, 255 },
- { 0, 0, 0, 255 }
- };
-
- if (col_a < col_b) {
- //punchrough
- table[2][0] = (int(table[0][0]) + int(table[1][0])) >> 1;
- table[2][1] = (int(table[0][1]) + int(table[1][1])) >> 1;
- table[2][2] = (int(table[0][2]) + int(table[1][2])) >> 1;
- table[3][3] = 0; //premul alpha black
- } else {
- //gradient
- table[2][0] = (int(table[0][0]) * 2 + int(table[1][0])) / 3;
- table[2][1] = (int(table[0][1]) * 2 + int(table[1][1])) / 3;
- table[2][2] = (int(table[0][2]) * 2 + int(table[1][2])) / 3;
- table[3][0] = (int(table[0][0]) + int(table[1][0]) * 2) / 3;
- table[3][1] = (int(table[0][1]) + int(table[1][1]) * 2) / 3;
- table[3][2] = (int(table[0][2]) + int(table[1][2]) * 2) / 3;
- }
-
- uint32_t block = src[4];
- block <<= 8;
- block |= src[5];
- block <<= 8;
- block |= src[6];
- block <<= 8;
- block |= src[7];
-
- int y = (j / (wd / 4)) * 4;
- int x = (j % (wd / 4)) * 4;
- int pixofs = (y * wd + x) * 4;
-
- for (int k = 0; k < 16; k++) {
- int idx = pixofs + ofs_table[k];
- dst[idx + 0] = table[block & 0x3][0];
- dst[idx + 1] = table[block & 0x3][1];
- dst[idx + 2] = table[block & 0x3][2];
- dst[idx + 3] = table[block & 0x3][3];
- block >>= 2;
- }
- }
-
- rofs += len * 8;
- wofs += wd * ht * 4;
-
- wd /= 2;
- ht /= 2;
-
- } break;
- case FORMAT_DXT3: {
-
- int len = (wd * ht) / 16;
- uint8_t *dst = &w[wofs];
-
- uint32_t ofs_table[16];
- for (int x = 0; x < 4; x++) {
-
- for (int y = 0; y < 4; y++) {
-
- ofs_table[15 - (y * 4 + (3 - x))] = (x + y * wd) * 4;
- }
- }
-
- for (int j = 0; j < len; j++) {
-
- const uint8_t *src = &r[rofs + j * 16];
-
- uint64_t ablock = src[1];
- ablock <<= 8;
- ablock |= src[0];
- ablock <<= 8;
- ablock |= src[3];
- ablock <<= 8;
- ablock |= src[2];
- ablock <<= 8;
- ablock |= src[5];
- ablock <<= 8;
- ablock |= src[4];
- ablock <<= 8;
- ablock |= src[7];
- ablock <<= 8;
- ablock |= src[6];
-
- uint16_t col_a = src[8 + 1];
- col_a <<= 8;
- col_a |= src[8 + 0];
- uint16_t col_b = src[8 + 3];
- col_b <<= 8;
- col_b |= src[8 + 2];
-
- uint8_t table[4][4] = {
- { uint8_t((col_a >> 11) << 3), uint8_t(((col_a >> 5) & 0x3f) << 2), uint8_t(((col_a)&0x1f) << 3), 255 },
- { uint8_t((col_b >> 11) << 3), uint8_t(((col_b >> 5) & 0x3f) << 2), uint8_t(((col_b)&0x1f) << 3), 255 },
-
- { 0, 0, 0, 255 },
- { 0, 0, 0, 255 }
- };
-
- //always gradient
- table[2][0] = (int(table[0][0]) * 2 + int(table[1][0])) / 3;
- table[2][1] = (int(table[0][1]) * 2 + int(table[1][1])) / 3;
- table[2][2] = (int(table[0][2]) * 2 + int(table[1][2])) / 3;
- table[3][0] = (int(table[0][0]) + int(table[1][0]) * 2) / 3;
- table[3][1] = (int(table[0][1]) + int(table[1][1]) * 2) / 3;
- table[3][2] = (int(table[0][2]) + int(table[1][2]) * 2) / 3;
-
- uint32_t block = src[4 + 8];
- block <<= 8;
- block |= src[5 + 8];
- block <<= 8;
- block |= src[6 + 8];
- block <<= 8;
- block |= src[7 + 8];
-
- int y = (j / (wd / 4)) * 4;
- int x = (j % (wd / 4)) * 4;
- int pixofs = (y * wd + x) * 4;
-
- for (int k = 0; k < 16; k++) {
- uint8_t alpha = ablock & 0xf;
- alpha = int(alpha) * 255 / 15; //right way for alpha
- int idx = pixofs + ofs_table[k];
- dst[idx + 0] = table[block & 0x3][0];
- dst[idx + 1] = table[block & 0x3][1];
- dst[idx + 2] = table[block & 0x3][2];
- dst[idx + 3] = alpha;
- block >>= 2;
- ablock >>= 4;
- }
- }
-
- rofs += len * 16;
- wofs += wd * ht * 4;
-
- wd /= 2;
- ht /= 2;
-
- } break;
- case FORMAT_DXT5: {
-
- int len = (wd * ht) / 16;
- uint8_t *dst = &w[wofs];
-
- uint32_t ofs_table[16];
- for (int x = 0; x < 4; x++) {
-
- for (int y = 0; y < 4; y++) {
-
- ofs_table[15 - (y * 4 + (3 - x))] = (x + y * wd) * 4;
- }
- }
-
- for (int j = 0; j < len; j++) {
-
- const uint8_t *src = &r[rofs + j * 16];
-
- uint8_t a_start = src[1];
- uint8_t a_end = src[0];
-
- uint64_t ablock = src[3];
- ablock <<= 8;
- ablock |= src[2];
- ablock <<= 8;
- ablock |= src[5];
- ablock <<= 8;
- ablock |= src[4];
- ablock <<= 8;
- ablock |= src[7];
- ablock <<= 8;
- ablock |= src[6];
-
- uint8_t atable[8];
-
- if (a_start > a_end) {
-
- atable[0] = (int(a_start) * 7 + int(a_end) * 0) / 7;
- atable[1] = (int(a_start) * 6 + int(a_end) * 1) / 7;
- atable[2] = (int(a_start) * 5 + int(a_end) * 2) / 7;
- atable[3] = (int(a_start) * 4 + int(a_end) * 3) / 7;
- atable[4] = (int(a_start) * 3 + int(a_end) * 4) / 7;
- atable[5] = (int(a_start) * 2 + int(a_end) * 5) / 7;
- atable[6] = (int(a_start) * 1 + int(a_end) * 6) / 7;
- atable[7] = (int(a_start) * 0 + int(a_end) * 7) / 7;
- } else {
-
- atable[0] = (int(a_start) * 5 + int(a_end) * 0) / 5;
- atable[1] = (int(a_start) * 4 + int(a_end) * 1) / 5;
- atable[2] = (int(a_start) * 3 + int(a_end) * 2) / 5;
- atable[3] = (int(a_start) * 2 + int(a_end) * 3) / 5;
- atable[4] = (int(a_start) * 1 + int(a_end) * 4) / 5;
- atable[5] = (int(a_start) * 0 + int(a_end) * 5) / 5;
- atable[6] = 0;
- atable[7] = 255;
- }
-
- uint16_t col_a = src[8 + 1];
- col_a <<= 8;
- col_a |= src[8 + 0];
- uint16_t col_b = src[8 + 3];
- col_b <<= 8;
- col_b |= src[8 + 2];
-
- uint8_t table[4][4] = {
- { uint8_t((col_a >> 11) << 3), uint8_t(((col_a >> 5) & 0x3f) << 2), uint8_t(((col_a)&0x1f) << 3), 255 },
- { uint8_t((col_b >> 11) << 3), uint8_t(((col_b >> 5) & 0x3f) << 2), uint8_t(((col_b)&0x1f) << 3), 255 },
-
- { 0, 0, 0, 255 },
- { 0, 0, 0, 255 }
- };
-
- //always gradient
- table[2][0] = (int(table[0][0]) * 2 + int(table[1][0])) / 3;
- table[2][1] = (int(table[0][1]) * 2 + int(table[1][1])) / 3;
- table[2][2] = (int(table[0][2]) * 2 + int(table[1][2])) / 3;
- table[3][0] = (int(table[0][0]) + int(table[1][0]) * 2) / 3;
- table[3][1] = (int(table[0][1]) + int(table[1][1]) * 2) / 3;
- table[3][2] = (int(table[0][2]) + int(table[1][2]) * 2) / 3;
-
- uint32_t block = src[4 + 8];
- block <<= 8;
- block |= src[5 + 8];
- block <<= 8;
- block |= src[6 + 8];
- block <<= 8;
- block |= src[7 + 8];
-
- int y = (j / (wd / 4)) * 4;
- int x = (j % (wd / 4)) * 4;
- int pixofs = (y * wd + x) * 4;
-
- for (int k = 0; k < 16; k++) {
- uint8_t alpha = ablock & 0x7;
- int idx = pixofs + ofs_table[k];
- dst[idx + 0] = table[block & 0x3][0];
- dst[idx + 1] = table[block & 0x3][1];
- dst[idx + 2] = table[block & 0x3][2];
- dst[idx + 3] = atable[alpha];
- block >>= 2;
- ablock >>= 3;
- }
- }
-
- rofs += len * 16;
- wofs += wd * ht * 4;
-
- wd /= 2;
- ht /= 2;
-
- } break;
- default: {}
- }
- }
-
- w = PoolVector<uint8_t>::Write();
- r = PoolVector<uint8_t>::Read();
-
- data = newdata;
- format = FORMAT_RGBA8;
- if (wd != width || ht != height) {
-
- SWAP(width, wd);
- SWAP(height, ht);
- crop(wd, ht);
- }
-
- return OK;
-}
-
bool Image::is_compressed() const {
return format >= FORMAT_RGB565;
}
Error Image::decompress() {
- if (format >= FORMAT_DXT1 && format <= FORMAT_ATI2)
- _decompress_bc(); //_image_decompress_bc(this);
+ if (format >= FORMAT_DXT1 && format <= FORMAT_ATI2 && _image_decompress_bc)
+ _image_decompress_bc(this);
else if (format >= FORMAT_PVRTC2 && format <= FORMAT_PVRTC4A && _image_decompress_pvrtc)
_image_decompress_pvrtc(this);
else if (format == FORMAT_ETC && _image_decompress_etc)
diff --git a/core/image.h b/core/image.h
index 4decaa3436..273e2d0ab7 100644
--- a/core/image.h
+++ b/core/image.h
@@ -227,7 +227,7 @@ public:
PoolVector<uint8_t> get_data() const;
Error load(const String &p_path);
- Error save_png(const String &p_path);
+ Error save_png(const String &p_path) const;
/**
* create an empty image