add EAC support
This commit is contained in:
@@ -284,8 +284,7 @@ static void decode_etc2a8_block(const uint8_t *data, uint32_t *outbuf) {
|
||||
// multiplier != 0
|
||||
const uint_fast8_t multiplier = data[1] >> 4;
|
||||
const int_fast8_t *table = Etc2AlphaModTable[data[1] & 0xf];
|
||||
uint_fast64_t l = data[7] | (uint_fast16_t)data[6] << 8 | (uint_fast32_t)data[5] << 16 |
|
||||
(uint_fast32_t)data[4] << 24 | (uint_fast64_t)data[3] << 32 | (uint_fast64_t)data[2] << 40;
|
||||
uint_fast64_t l = bton64(*(uint64_t*)data);
|
||||
for (int i = 0; i < 16; i++, l >>= 3)
|
||||
((uint8_t *)(outbuf + WriteOrderTableRev[i]))[3] = clamp(data[0] + multiplier * table[l & 7]);
|
||||
} else {
|
||||
@@ -295,6 +294,31 @@ static void decode_etc2a8_block(const uint8_t *data, uint32_t *outbuf) {
|
||||
}
|
||||
}
|
||||
|
||||
static void decode_eac_block(const uint8_t *data, int color, uint32_t *outbuf) {
|
||||
uint_fast8_t multiplier = data[1] >> 1 & 0x78;
|
||||
if (multiplier == 0)
|
||||
multiplier = 1;
|
||||
const int_fast8_t *table = Etc2AlphaModTable[data[1] & 0xf];
|
||||
uint_fast64_t l = bton64(*(uint64_t*)data);
|
||||
for (int i = 0; i < 16; i++, l >>= 3) {
|
||||
int_fast16_t val = data[0] * 8 + multiplier * table[l & 7] + 4;
|
||||
((uint8_t *)(outbuf + WriteOrderTableRev[i]))[color] = val < 0 ? 0 : val >= 2048 ? 0xff : val >> 3;
|
||||
}
|
||||
}
|
||||
|
||||
static void decode_eac_signed_block(const uint8_t *data, int color, uint32_t *outbuf) {
|
||||
int8_t base = (int8_t)data[0];
|
||||
uint_fast8_t multiplier = data[1] >> 1 & 0x78;
|
||||
if (multiplier == 0)
|
||||
multiplier = 1;
|
||||
const int_fast8_t *table = Etc2AlphaModTable[data[1] & 0xf];
|
||||
uint_fast64_t l = bton64(*(uint64_t*)data);
|
||||
for (int i = 0; i < 16; i++, l >>= 3) {
|
||||
int_fast16_t val = base * 8 + multiplier * table[l & 7] + 1023;
|
||||
((uint8_t *)(outbuf + WriteOrderTableRev[i]))[color] = val < 0 ? 0 : val >= 2048 ? 0xff : val >> 3;
|
||||
}
|
||||
}
|
||||
|
||||
int decode_etc1(const uint8_t *data, const long w, const long h, uint32_t *image) {
|
||||
long num_blocks_x = (w + 3) / 4;
|
||||
long num_blocks_y = (h + 3) / 4;
|
||||
@@ -347,3 +371,73 @@ int decode_etc2a8(const uint8_t *data, const long w, const long h, uint32_t *ima
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int decode_eacr(const uint8_t *data, const long w, const long h, uint32_t *image) {
|
||||
long num_blocks_x = (w + 3) / 4;
|
||||
long num_blocks_y = (h + 3) / 4;
|
||||
uint32_t buffer[16];
|
||||
uint32_t base_buffer[16];
|
||||
for (int i = 0; i < 16; i++)
|
||||
base_buffer[i] = color(0, 0, 0, 255);
|
||||
for (long by = 0; by < num_blocks_y; by++) {
|
||||
for (long bx = 0; bx < num_blocks_x; bx++, data += 8) {
|
||||
memcpy(buffer, base_buffer, sizeof(buffer));
|
||||
decode_eac_block(data, 0, buffer);
|
||||
copy_block_buffer(bx, by, w, h, 4, 4, buffer, image);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int decode_eacr_signed(const uint8_t *data, const long w, const long h, uint32_t *image) {
|
||||
long num_blocks_x = (w + 3) / 4;
|
||||
long num_blocks_y = (h + 3) / 4;
|
||||
uint32_t buffer[16];
|
||||
uint32_t base_buffer[16];
|
||||
for (int i = 0; i < 16; i++)
|
||||
base_buffer[i] = color(0, 0, 0, 255);
|
||||
for (long by = 0; by < num_blocks_y; by++) {
|
||||
for (long bx = 0; bx < num_blocks_x; bx++, data += 8) {
|
||||
memcpy(buffer, base_buffer, sizeof(buffer));
|
||||
decode_eac_signed_block(data, 0, buffer);
|
||||
copy_block_buffer(bx, by, w, h, 4, 4, buffer, image);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int decode_eacrg(const uint8_t *data, const long w, const long h, uint32_t *image) {
|
||||
long num_blocks_x = (w + 3) / 4;
|
||||
long num_blocks_y = (h + 3) / 4;
|
||||
uint32_t buffer[16];
|
||||
uint32_t base_buffer[16];
|
||||
for (int i = 0; i < 16; i++)
|
||||
base_buffer[i] = color(0, 0, 0, 255);
|
||||
for (long by = 0; by < num_blocks_y; by++) {
|
||||
for (long bx = 0; bx < num_blocks_x; bx++, data += 16) {
|
||||
memcpy(buffer, base_buffer, sizeof(buffer));
|
||||
decode_eac_block(data, 0, buffer);
|
||||
decode_eac_block(data + 8, 1, buffer);
|
||||
copy_block_buffer(bx, by, w, h, 4, 4, buffer, image);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int decode_eacrg_signed(const uint8_t *data, const long w, const long h, uint32_t *image) {
|
||||
long num_blocks_x = (w + 3) / 4;
|
||||
long num_blocks_y = (h + 3) / 4;
|
||||
uint32_t buffer[16];
|
||||
uint32_t base_buffer[16];
|
||||
for (int i = 0; i < 16; i++)
|
||||
base_buffer[i] = color(0, 0, 0, 255);
|
||||
for (long by = 0; by < num_blocks_y; by++) {
|
||||
for (long bx = 0; bx < num_blocks_x; bx++, data += 16) {
|
||||
memcpy(buffer, base_buffer, sizeof(buffer));
|
||||
decode_eac_signed_block(data, 0, buffer);
|
||||
decode_eac_signed_block(data + 8, 1, buffer);
|
||||
copy_block_buffer(bx, by, w, h, 4, 4, buffer, image);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -7,5 +7,9 @@ int decode_etc1(const uint8_t *, const long, const long, uint32_t *);
|
||||
int decode_etc2(const uint8_t *, const long, const long, uint32_t *);
|
||||
int decode_etc2a1(const uint8_t *, const long, const long, uint32_t *);
|
||||
int decode_etc2a8(const uint8_t *, const long, const long, uint32_t *);
|
||||
int decode_eacr(const uint8_t *, const long, const long, uint32_t *);
|
||||
int decode_eacr_signed(const uint8_t *, const long, const long, uint32_t *);
|
||||
int decode_eacrg(const uint8_t *, const long, const long, uint32_t *);
|
||||
int decode_eacrg_signed(const uint8_t *, const long, const long, uint32_t *);
|
||||
|
||||
#endif /* end of include guard: ETC_H */
|
||||
|
||||
@@ -194,8 +194,8 @@ static VALUE rb_decode_etc1(VALUE self, VALUE rb_data, VALUE rb_w, VALUE rb_h) {
|
||||
* Decode image from ETC2 compressed binary
|
||||
*
|
||||
* @param [String] rb_data binary to decode
|
||||
* @param [Integer] w image width
|
||||
* @param [Integer] h image height
|
||||
* @param [Integer] rb_w image width
|
||||
* @param [Integer] rb_h image height
|
||||
* @return [String] decoded rgba binary
|
||||
*/
|
||||
static VALUE rb_decode_etc2(VALUE self, VALUE rb_data, VALUE rb_w, VALUE rb_h) {
|
||||
@@ -212,8 +212,8 @@ static VALUE rb_decode_etc2(VALUE self, VALUE rb_data, VALUE rb_w, VALUE rb_h) {
|
||||
* Decode image from ETC2 Alpha1 compressed binary
|
||||
*
|
||||
* @param [String] rb_data binary to decode
|
||||
* @param [Integer] w image width
|
||||
* @param [Integer] h image height
|
||||
* @param [Integer] rb_w image width
|
||||
* @param [Integer] rb_h image height
|
||||
* @return [String] decoded rgba binary
|
||||
*/
|
||||
static VALUE rb_decode_etc2a1(VALUE self, VALUE rb_data, VALUE rb_w, VALUE rb_h) {
|
||||
@@ -230,8 +230,8 @@ static VALUE rb_decode_etc2a1(VALUE self, VALUE rb_data, VALUE rb_w, VALUE rb_h)
|
||||
* Decode image from ETC2 Alpha8 compressed binary
|
||||
*
|
||||
* @param [String] rb_data binary to decode
|
||||
* @param [Integer] w image width
|
||||
* @param [Integer] h image height
|
||||
* @param [Integer] rb_w image width
|
||||
* @param [Integer] rb_h image height
|
||||
* @return [String] decoded rgba binary
|
||||
*/
|
||||
static VALUE rb_decode_etc2a8(VALUE self, VALUE rb_data, VALUE rb_w, VALUE rb_h) {
|
||||
@@ -244,6 +244,78 @@ static VALUE rb_decode_etc2a8(VALUE self, VALUE rb_data, VALUE rb_w, VALUE rb_h)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode image from EAC R11 compressed binary
|
||||
*
|
||||
* @param [String] rb_data binary to decode
|
||||
* @param [Integer] rb_w image width
|
||||
* @param [Integer] rb_h image height
|
||||
* @return [String] decoded rgba binary
|
||||
*/
|
||||
static VALUE rb_decode_eacr(VALUE self, VALUE rb_data, VALUE rb_w, VALUE rb_h) {
|
||||
long w = FIX2LONG(rb_w), h = FIX2LONG(rb_h);
|
||||
if (!check_str_len_block(rb_data, w, h, 4, 4, 8))
|
||||
return Qnil;
|
||||
VALUE ret = rb_alloc_rgba(w * h);
|
||||
if (!decode_eacr((uint8_t *)RSTRING_PTR(rb_data), w, h, (uint32_t *)RSTRING_PTR(ret)))
|
||||
return Qnil;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode image from EAC Signed R11 compressed binary
|
||||
*
|
||||
* @param [String] rb_data binary to decode
|
||||
* @param [Integer] rb_w image width
|
||||
* @param [Integer] rb_h image height
|
||||
* @return [String] decoded rgba binary
|
||||
*/
|
||||
static VALUE rb_decode_eacsr(VALUE self, VALUE rb_data, VALUE rb_w, VALUE rb_h) {
|
||||
long w = FIX2LONG(rb_w), h = FIX2LONG(rb_h);
|
||||
if (!check_str_len_block(rb_data, w, h, 4, 4, 8))
|
||||
return Qnil;
|
||||
VALUE ret = rb_alloc_rgba(w * h);
|
||||
if (!decode_eacr_signed((uint8_t *)RSTRING_PTR(rb_data), w, h, (uint32_t *)RSTRING_PTR(ret)))
|
||||
return Qnil;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode image from EAC RG11 compressed binary
|
||||
*
|
||||
* @param [String] rb_data binary to decode
|
||||
* @param [Integer] rb_w image width
|
||||
* @param [Integer] rb_h image height
|
||||
* @return [String] decoded rgba binary
|
||||
*/
|
||||
static VALUE rb_decode_eacrg(VALUE self, VALUE rb_data, VALUE rb_w, VALUE rb_h) {
|
||||
long w = FIX2LONG(rb_w), h = FIX2LONG(rb_h);
|
||||
if (!check_str_len_block(rb_data, w, h, 4, 4, 16))
|
||||
return Qnil;
|
||||
VALUE ret = rb_alloc_rgba(w * h);
|
||||
if (!decode_eacrg((uint8_t *)RSTRING_PTR(rb_data), w, h, (uint32_t *)RSTRING_PTR(ret)))
|
||||
return Qnil;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode image from EAC RG11 compressed binary
|
||||
*
|
||||
* @param [String] rb_data binary to decode
|
||||
* @param [Integer] rb_w image width
|
||||
* @param [Integer] rb_h image height
|
||||
* @return [String] decoded rgba binary
|
||||
*/
|
||||
static VALUE rb_decode_eacsrg(VALUE self, VALUE rb_data, VALUE rb_w, VALUE rb_h) {
|
||||
long w = FIX2LONG(rb_w), h = FIX2LONG(rb_h);
|
||||
if (!check_str_len_block(rb_data, w, h, 4, 4, 16))
|
||||
return Qnil;
|
||||
VALUE ret = rb_alloc_rgba(w * h);
|
||||
if (!decode_eacrg_signed((uint8_t *)RSTRING_PTR(rb_data), w, h, (uint32_t *)RSTRING_PTR(ret)))
|
||||
return Qnil;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode image from ASTC compressed binary
|
||||
*
|
||||
@@ -336,6 +408,10 @@ void Init_native() {
|
||||
rb_define_module_function(mDecodeHelper, "decode_etc2", rb_decode_etc2, 3);
|
||||
rb_define_module_function(mDecodeHelper, "decode_etc2a1", rb_decode_etc2a1, 3);
|
||||
rb_define_module_function(mDecodeHelper, "decode_etc2a8", rb_decode_etc2a8, 3);
|
||||
rb_define_module_function(mDecodeHelper, "decode_eacr", rb_decode_eacr, 3);
|
||||
rb_define_module_function(mDecodeHelper, "decode_eacsr", rb_decode_eacsr, 3);
|
||||
rb_define_module_function(mDecodeHelper, "decode_eacrg", rb_decode_eacrg, 3);
|
||||
rb_define_module_function(mDecodeHelper, "decode_eacsrg", rb_decode_eacsrg, 3);
|
||||
rb_define_module_function(mDecodeHelper, "decode_astc", rb_decode_astc, 5);
|
||||
rb_define_module_function(mDecodeHelper, "decode_dxt1", rb_decode_dxt1, 3);
|
||||
rb_define_module_function(mDecodeHelper, "decode_dxt5", rb_decode_dxt5, 3);
|
||||
|
||||
Reference in New Issue
Block a user