mikunyan 3.9.4 → 3.9.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/README.md +35 -41
- data/Rakefile +9 -0
- data/exe/mikunyan-image +12 -8
- data/ext/decoders/native/astc.c +760 -0
- data/ext/decoders/native/astc.h +8 -0
- data/ext/decoders/native/dxtc.c +104 -0
- data/ext/decoders/native/dxtc.h +9 -0
- data/ext/decoders/native/etc.c +271 -0
- data/ext/decoders/native/etc.h +11 -0
- data/ext/decoders/native/extconf.rb +8 -0
- data/ext/decoders/native/main.c +167 -0
- data/ext/decoders/native/rgb.c +26 -0
- data/ext/decoders/native/rgb.h +8 -0
- data/lib/mikunyan/asset.rb +13 -7
- data/lib/mikunyan/decoders/image_decoder.rb +40 -201
- data/lib/mikunyan/typetrees/00ad972a9b8de1baeacb62e297cbb968.dat +0 -0
- data/lib/mikunyan/typetrees/01ccfe05c6fbc7ff03dcf8afa8213ff5.dat +0 -0
- data/lib/mikunyan/typetrees/086efb68ee41abe4e98e1ae93ae96290.dat +0 -0
- data/lib/mikunyan/typetrees/10355709bc95355f57466913ac850d0b.dat +0 -0
- data/lib/mikunyan/typetrees/1e87d82d4fd058509a3c7866db0e7356.dat +0 -0
- data/lib/mikunyan/typetrees/26165a24a953362edb6a7078f6536c4b.dat +0 -0
- data/lib/mikunyan/typetrees/266d53113fa30d2b858f2768f92eaa14.dat +0 -0
- data/lib/mikunyan/typetrees/2d2b1d63eb2a68ed94bbf7f50fc21d7b.dat +0 -0
- data/lib/mikunyan/typetrees/434b934f757d042e20f52d8c2ae20843.dat +0 -0
- data/lib/mikunyan/typetrees/486ba4e15dbd6aea8ac1a064305889c8.dat +0 -0
- data/lib/mikunyan/typetrees/49ff511929094ac12ffaa4ab38ed7bd1.dat +0 -0
- data/lib/mikunyan/typetrees/4dbfaa1def6adb569b550804b19b4305.dat +0 -0
- data/lib/mikunyan/typetrees/5bc42b93159267aabba724a6a7923603.dat +0 -0
- data/lib/mikunyan/typetrees/66405447c6973a81e978410c391172fe.dat +0 -0
- data/lib/mikunyan/typetrees/6932d6d1d46264c8680a181056f98be2.dat +0 -0
- data/lib/mikunyan/typetrees/6974f6c74321933ec4ba7437a55be2c3.dat +0 -0
- data/lib/mikunyan/typetrees/69b01db128625aa95f1f92fb890ff045.dat +0 -0
- data/lib/mikunyan/typetrees/6f10d8f832d5adde6982d4515b3f0bb3.dat +0 -0
- data/lib/mikunyan/typetrees/761ca81f78491542badc37f810ab3455.dat +0 -0
- data/lib/mikunyan/typetrees/76ce55d4dbaf38f5c674ea9f0a344951.dat +0 -0
- data/lib/mikunyan/typetrees/7e050781d08ca9d10bc74beb7e91c3b5.dat +0 -0
- data/lib/mikunyan/typetrees/8198e72b2e2a96b9cfa38636b5565e13.dat +0 -0
- data/lib/mikunyan/typetrees/84c6ac46ef89030991cbbb3fd21d2889.dat +0 -0
- data/lib/mikunyan/typetrees/852794becbcf95f66992da2b96a69704.dat +0 -0
- data/lib/mikunyan/typetrees/961be27d12d60b1b3421191d5256a876.dat +0 -0
- data/lib/mikunyan/typetrees/96a47566b4e135078f690a4a69935d58.dat +0 -0
- data/lib/mikunyan/typetrees/97da5f4688e45a57c8b42d4f42497297.dat +0 -0
- data/lib/mikunyan/typetrees/97ec0712102a3ea3f1cf8c0a4e47c070.dat +0 -0
- data/lib/mikunyan/typetrees/9eabac6ec66ffe818e008883728fcc1b.dat +0 -0
- data/lib/mikunyan/typetrees/a372646834bcaf26eab1d21b29e39553.dat +0 -0
- data/lib/mikunyan/typetrees/a4f194097b08bc4c5019c3a4ea6f5cbd.dat +0 -0
- data/lib/mikunyan/typetrees/af863b6969b9b82be9450f0574339f65.dat +0 -0
- data/lib/mikunyan/typetrees/b0adafbe24f8148ebf01794ee6679925.dat +0 -0
- data/lib/mikunyan/typetrees/b14bcb0865632d1b2d6e215a000e4c0f.dat +0 -0
- data/lib/mikunyan/typetrees/b35bf02952f2946208ff6b4deca3a6a9.dat +0 -0
- data/lib/mikunyan/typetrees/b6bbd0e88d1feb636d89bd766ea5934f.dat +0 -0
- data/lib/mikunyan/typetrees/b78821b6aeb5b79c8961728a9f068024.dat +0 -0
- data/lib/mikunyan/typetrees/bea915a8ab3d9b55e80c969a22e692d3.dat +0 -0
- data/lib/mikunyan/typetrees/c184743520186f546000de20f4d19736.dat +0 -0
- data/lib/mikunyan/typetrees/d50ed13362e98df8096b2f735131fce5.dat +0 -0
- data/lib/mikunyan/typetrees/d871346d990bbc294d02f4c366bf1b6d.dat +0 -0
- data/lib/mikunyan/typetrees/d8e8eeb43589ccd7019398e56f6c16b0.dat +0 -0
- data/lib/mikunyan/typetrees/daea1bb1bba6613afb2cb001ca8fa0d4.dat +0 -0
- data/lib/mikunyan/typetrees/db088f9c2f2224da9f488879467856e5.dat +0 -0
- data/lib/mikunyan/typetrees/e7c5c01b0369574e9346ce846e1e8e63.dat +0 -0
- data/lib/mikunyan/typetrees/f123b055a61dfa7dc679d78cdaecd383.dat +0 -0
- data/lib/mikunyan/typetrees/f92d618c5266ea3a8ca770b6eca728c8.dat +0 -0
- data/lib/mikunyan/typetrees/fad2d0a58e9174708176102b418facf1.dat +0 -0
- data/lib/mikunyan/typetrees/ff001a2e51937aa5add9eaf9cd3d8ae4.dat +0 -0
- data/lib/mikunyan/version.rb +1 -1
- data/mikunyan.gemspec +1 -0
- metadata +63 -4
- data/lib/mikunyan/decoders/astc_block_decoder.rb +0 -526
@@ -0,0 +1,26 @@
|
|
1
|
+
#include <stdint.h>
|
2
|
+
|
3
|
+
static inline int is_system_little() {
|
4
|
+
int x = 1;
|
5
|
+
return *(char*)&x == 1;
|
6
|
+
}
|
7
|
+
|
8
|
+
void decode_rgb565(const uint16_t* data, const int size, const int is_big_endian, uint8_t* image) {
|
9
|
+
const uint16_t *d = data;
|
10
|
+
if (is_big_endian == is_system_little()) {
|
11
|
+
uint8_t *p = image;
|
12
|
+
for (int i = 0; i < size; i++, d++, p += 4) {
|
13
|
+
uint_fast8_t r = *d & 0x00f8;
|
14
|
+
uint_fast8_t g = (*d & 0x0007) << 5 | (*d & 0xe000) >> 11;
|
15
|
+
uint_fast8_t b = (*d & 0x1f00) >> 5;
|
16
|
+
p[0] = r | r >> 5;
|
17
|
+
p[1] = g | g >> 6;
|
18
|
+
p[2] = b | b >> 5;
|
19
|
+
p[3] = 255;
|
20
|
+
}
|
21
|
+
} else {
|
22
|
+
uint32_t *p = (uint32_t*)image;
|
23
|
+
for (int i = 0; i < size; i++, d++, p++)
|
24
|
+
*p = (*d & 0xf800) >> 8 | *d >> 13 | (*d & 0x7e0) << 5 | (*d & 0x60) << 3 | *d << 19 | (*d & 0x1c) << 14 | 0xff000000;
|
25
|
+
}
|
26
|
+
}
|
data/lib/mikunyan/asset.rb
CHANGED
@@ -226,19 +226,25 @@ module Mikunyan
|
|
226
226
|
children = type_tree[:children]
|
227
227
|
|
228
228
|
if node.array?
|
229
|
-
data =
|
230
|
-
size = parse_object_private(br, children.find{|e| e[:name] == 'size'})
|
229
|
+
data = nil
|
230
|
+
size = parse_object_private(br, children.find{|e| e[:name] == 'size'}).value
|
231
231
|
data_type_tree = children.find{|e| e[:name] == 'data'}
|
232
|
-
|
233
|
-
data
|
232
|
+
if node.type == 'TypelessData'
|
233
|
+
data = br.read(size * data_type_tree[:node].size)
|
234
|
+
else
|
235
|
+
data = size.times.map{ parse_object_private(br, data_type_tree) }
|
234
236
|
end
|
235
|
-
data = data.map{|e| e.value}.pack('C*') if node.type == 'TypelessData'
|
236
237
|
r = ObjectValue.new(node.name, node.type, br.endian, data)
|
237
238
|
elsif node.size == -1
|
238
239
|
r = ObjectValue.new(node.name, node.type, br.endian)
|
239
240
|
if children.size == 1 && children[0][:name] == 'Array' && children[0][:node].type == 'Array' && children[0][:node].array?
|
240
|
-
|
241
|
-
|
241
|
+
if node.type == 'string'
|
242
|
+
size = parse_object_private(br, children[0][:children].find{|e| e[:name] == 'size'}).value
|
243
|
+
r.value = br.read(size * children[0][:children].find{|e| e[:name] == 'data'}[:node].size).force_encoding("utf-8")
|
244
|
+
br.align(4) if children[0][:node].flags & 0x4000 != 0
|
245
|
+
else
|
246
|
+
r.value = parse_object_private(br, children[0]).value
|
247
|
+
end
|
242
248
|
else
|
243
249
|
children.each do |child|
|
244
250
|
r[child[:name]] = parse_object_private(br, child)
|
@@ -1,7 +1,6 @@
|
|
1
1
|
begin; require 'oily_png'; rescue LoadError; require 'chunky_png'; end
|
2
2
|
require 'bin_utils'
|
3
|
-
require '
|
4
|
-
require 'mikunyan/decoders/astc_block_decoder'
|
3
|
+
require 'mikunyan/decoders/native'
|
5
4
|
|
6
5
|
module Mikunyan
|
7
6
|
# Class for image decoding tools
|
@@ -39,6 +38,10 @@ module Mikunyan
|
|
39
38
|
decode_rgb565(width, height, bin, endian)
|
40
39
|
when 9
|
41
40
|
decode_r16(width, height, bin)
|
41
|
+
when 10
|
42
|
+
decode_dxt1(width, height, bin)
|
43
|
+
when 12
|
44
|
+
decode_dxt5(width, height, bin)
|
42
45
|
when 13
|
43
46
|
decode_rgba4444(width, height, bin, endian)
|
44
47
|
when 14
|
@@ -61,6 +64,8 @@ module Mikunyan
|
|
61
64
|
decode_etc1(width, height, bin)
|
62
65
|
when 45
|
63
66
|
decode_etc2rgb(width, height, bin)
|
67
|
+
when 46
|
68
|
+
decode_etc2rgba1(width, height, bin)
|
64
69
|
when 47
|
65
70
|
decode_etc2rgba8(width, height, bin)
|
66
71
|
when 48, 54
|
@@ -123,15 +128,7 @@ module Mikunyan
|
|
123
128
|
# @param [Symbol] endian endianness of binary
|
124
129
|
# @return [ChunkyPNG::Image] decoded image
|
125
130
|
def self.decode_rgb565(width, height, bin, endian = :big)
|
126
|
-
|
127
|
-
(width * height).times do |i|
|
128
|
-
c = endian == :little ? BinUtils.get_int16_le(bin, i*2) : BinUtils.get_int16_be(bin, i*2)
|
129
|
-
r = (c & 0xf800) >> 8
|
130
|
-
g = (c & 0x07e0) >> 3
|
131
|
-
b = (c & 0x001f) << 3
|
132
|
-
BinUtils.append_int8!(mem, r | r >> 5, g | g >> 6, b | b >> 5)
|
133
|
-
end
|
134
|
-
ChunkyPNG::Image.from_rgb_stream(width, height, mem).flip
|
131
|
+
ChunkyPNG::Image.from_rgba_stream(width, height, DecodeHelper.decode_rgb565(bin, width * height, endian == :big)).flip
|
135
132
|
end
|
136
133
|
|
137
134
|
# Decode image from A8 binary
|
@@ -154,7 +151,7 @@ module Mikunyan
|
|
154
151
|
# @param [String] bin binary to decode
|
155
152
|
# @return [ChunkyPNG::Image] decoded image
|
156
153
|
def self.decode_r8(width, height, bin)
|
157
|
-
decode_a8(width, height, bin)
|
154
|
+
decode_a8(width, height, bin)
|
158
155
|
end
|
159
156
|
|
160
157
|
# Decode image from RG16 binary
|
@@ -351,22 +348,31 @@ module Mikunyan
|
|
351
348
|
ChunkyPNG::Image.from_rgba_stream(width, height, mem).flip
|
352
349
|
end
|
353
350
|
|
351
|
+
# Decode image from DXT1 compressed binary
|
352
|
+
# @param [Integer] width image width
|
353
|
+
# @param [Integer] height image height
|
354
|
+
# @param [String] bin binary to decode
|
355
|
+
# @return [ChunkyPNG::Image] decoded image
|
356
|
+
def self.decode_dxt1(width, height, bin)
|
357
|
+
ChunkyPNG::Image.from_rgba_stream(width, height, DecodeHelper.decode_dxt1(bin, width, height))
|
358
|
+
end
|
359
|
+
|
360
|
+
# Decode image from DXT5 compressed binary
|
361
|
+
# @param [Integer] width image width
|
362
|
+
# @param [Integer] height image height
|
363
|
+
# @param [String] bin binary to decode
|
364
|
+
# @return [ChunkyPNG::Image] decoded image
|
365
|
+
def self.decode_dxt5(width, height, bin)
|
366
|
+
ChunkyPNG::Image.from_rgba_stream(width, height, DecodeHelper.decode_dxt5(bin, width, height))
|
367
|
+
end
|
368
|
+
|
354
369
|
# Decode image from ETC1 compressed binary
|
355
370
|
# @param [Integer] width image width
|
356
371
|
# @param [Integer] height image height
|
357
372
|
# @param [String] bin binary to decode
|
358
373
|
# @return [ChunkyPNG::Image] decoded image
|
359
374
|
def self.decode_etc1(width, height, bin)
|
360
|
-
|
361
|
-
bh = (height + 3) / 4
|
362
|
-
ret = ChunkyPNG::Image.new(bh * 4, bw * 4)
|
363
|
-
bh.times do |by|
|
364
|
-
bw.times do |bx|
|
365
|
-
block = decode_etc1_block(BinUtils.get_sint64_be(bin, (bx + by * bw) * 8))
|
366
|
-
ret.replace!(ChunkyPNG::Image.from_rgb_stream(4, 4, block), by * 4, bx * 4)
|
367
|
-
end
|
368
|
-
end
|
369
|
-
ret.crop(0, 0, height, width).rotate_left
|
375
|
+
ChunkyPNG::Image.from_rgba_stream(width, height, DecodeHelper.decode_etc1(bin, width, height))
|
370
376
|
end
|
371
377
|
|
372
378
|
# Decode image from ETC2 compressed binary
|
@@ -375,16 +381,16 @@ module Mikunyan
|
|
375
381
|
# @param [String] bin binary to decode
|
376
382
|
# @return [ChunkyPNG::Image] decoded image
|
377
383
|
def self.decode_etc2rgb(width, height, bin)
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
384
|
+
ChunkyPNG::Image.from_rgba_stream(width, height, DecodeHelper.decode_etc2(bin, width, height))
|
385
|
+
end
|
386
|
+
|
387
|
+
# Decode image from ETC2 Alpha1 compressed binary
|
388
|
+
# @param [Integer] width image width
|
389
|
+
# @param [Integer] height image height
|
390
|
+
# @param [String] bin binary to decode
|
391
|
+
# @return [ChunkyPNG::Image] decoded image
|
392
|
+
def self.decode_etc2rgba1(width, height, bin)
|
393
|
+
ChunkyPNG::Image.from_rgba_stream(width, height, DecodeHelper.decode_etc2a1(bin, width, height))
|
388
394
|
end
|
389
395
|
|
390
396
|
# Decode image from ETC2 Alpha8 compressed binary
|
@@ -393,19 +399,7 @@ module Mikunyan
|
|
393
399
|
# @param [String] bin binary to decode
|
394
400
|
# @return [ChunkyPNG::Image] decoded image
|
395
401
|
def self.decode_etc2rgba8(width, height, bin)
|
396
|
-
|
397
|
-
bh = (height + 3) / 4
|
398
|
-
ret = ChunkyPNG::Image.new(bh * 4, bw * 4)
|
399
|
-
bh.times do |by|
|
400
|
-
bw.times do |bx|
|
401
|
-
alpha = decode_etc2alpha_block(BinUtils.get_int64_be(bin, (bx + by * bw) * 16))
|
402
|
-
block = decode_etc2_block(BinUtils.get_int64_be(bin, (bx + by * bw) * 16 + 8))
|
403
|
-
mem = String.new(capacity: 64)
|
404
|
-
16.times{|i| mem << block[i] + alpha[i]}
|
405
|
-
ret.replace!(ChunkyPNG::Image.from_rgba_stream(4, 4, mem), by * 4, bx * 4)
|
406
|
-
end
|
407
|
-
end
|
408
|
-
ret.crop(0, 0, height, width).rotate_left
|
402
|
+
ChunkyPNG::Image.from_rgba_stream(width, height, DecodeHelper.decode_etc2a8(bin, width, height))
|
409
403
|
end
|
410
404
|
|
411
405
|
# Decode image from ASTC compressed binary
|
@@ -415,16 +409,7 @@ module Mikunyan
|
|
415
409
|
# @param [String] bin binary to decode
|
416
410
|
# @return [ChunkyPNG::Image] decoded image
|
417
411
|
def self.decode_astc(width, height, blocksize, bin)
|
418
|
-
|
419
|
-
bh = (height + blocksize - 1) / blocksize
|
420
|
-
ret = ChunkyPNG::Image.new(bw * blocksize, bh * blocksize)
|
421
|
-
bh.times do |by|
|
422
|
-
bw.times do |bx|
|
423
|
-
block = DecodeHelper::AstcBlockDecoder.new(bin.byteslice((by * bw + bx) * 16, 16), blocksize, blocksize).data
|
424
|
-
ret.replace!(ChunkyPNG::Image.from_rgba_stream(blocksize, blocksize, block), bx * blocksize, by * blocksize)
|
425
|
-
end
|
426
|
-
end
|
427
|
-
ret.crop(0, 0, width, height).flip
|
412
|
+
ChunkyPNG::Image.from_rgba_stream(width, height, DecodeHelper.decode_astc(bin, width, height, blocksize, blocksize))
|
428
413
|
end
|
429
414
|
|
430
415
|
# Create ASTC file data from ObjectValue
|
@@ -457,152 +442,6 @@ module Mikunyan
|
|
457
442
|
|
458
443
|
private
|
459
444
|
|
460
|
-
Etc1ModifierTable = [[2, 8], [5, 17], [9, 29], [13, 42], [18, 60], [24, 80], [33, 106], [47, 183]]
|
461
|
-
Etc1SubblockTable = [[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1], [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1]]
|
462
|
-
Etc2DistanceTable = [3, 6, 11, 16, 23, 32, 41, 64]
|
463
|
-
Etc2AlphaModTable = [
|
464
|
-
[-3, -6, -9, -15, 2, 5, 8, 14],
|
465
|
-
[-3, -7, -10, -13, 2, 6, 9, 12],
|
466
|
-
[-2, -5, -8, -13, 1, 4, 7, 12],
|
467
|
-
[-2, -4, -6, -13, 1, 3, 5, 12],
|
468
|
-
[-3, -6, -8, -12, 2, 5, 7, 11],
|
469
|
-
[-3, -7, -9, -11, 2, 6, 8, 10],
|
470
|
-
[-4, -7, -8, -11, 3, 6, 7, 10],
|
471
|
-
[-3, -5, -8, -11, 2, 4, 7, 10],
|
472
|
-
[-2, -6, -8, -10, 1, 5, 7, 9],
|
473
|
-
[-2, -5, -8, -10, 1, 4, 7, 9],
|
474
|
-
[-2, -4, -8, -10, 1, 3, 7, 9],
|
475
|
-
[-2, -5, -7, -10, 1, 4, 6, 9],
|
476
|
-
[-3, -4, -7, -10, 2, 3, 6, 9],
|
477
|
-
[-1, -2, -3, -10, 0, 1, 2, 9],
|
478
|
-
[-4, -6, -8, -9, 3, 5, 7, 8],
|
479
|
-
[-3, -5, -7, -9, 2, 4, 6, 8]
|
480
|
-
]
|
481
|
-
|
482
|
-
def self.decode_etc1_block(bin)
|
483
|
-
colors = []
|
484
|
-
codes = [bin >> 37 & 7, bin >> 34 & 7]
|
485
|
-
subblocks = Etc1SubblockTable[bin[32]]
|
486
|
-
if bin[33] == 0
|
487
|
-
colors[0] = bin >> 40 & 0xf0f0f0
|
488
|
-
colors[0] = colors[0] | colors[0] >> 4
|
489
|
-
colors[1] = bin >> 36 & 0xf0f0f0
|
490
|
-
colors[1] = colors[1] | colors[1] >> 4
|
491
|
-
else
|
492
|
-
colors[0] = bin >> 40 & 0xf8f8f8
|
493
|
-
dr = (bin >> 56 & 3) - (bin >> 56 & 4)
|
494
|
-
dg = (bin >> 48 & 3) - (bin >> 48 & 4)
|
495
|
-
db = (bin >> 40 & 3) - (bin >> 40 & 4)
|
496
|
-
colors[1] = colors[0] + (dr << 19) + (dg << 11) + (db << 3)
|
497
|
-
colors[0] = colors[0] | (colors[0] >> 5 & 0x70707)
|
498
|
-
colors[1] = colors[1] | (colors[1] >> 5 & 0x70707)
|
499
|
-
end
|
500
|
-
|
501
|
-
mem = Fiddle::Pointer.malloc(48)
|
502
|
-
16.times do |i|
|
503
|
-
modifier = Etc1ModifierTable[codes[subblocks[i]]][bin[i]]
|
504
|
-
mem[i * 3, 3] = etc1colormod(colors[subblocks[i]], bin[i + 16] == 0 ? modifier : -modifier)
|
505
|
-
end
|
506
|
-
mem.to_str
|
507
|
-
end
|
508
|
-
|
509
|
-
def self.etc1colormod(color, modifier)
|
510
|
-
r = (color >> 16 & 0xff) + modifier
|
511
|
-
g = (color >> 8 & 0xff) + modifier
|
512
|
-
b = (color & 0xff) + modifier
|
513
|
-
r.clamp(0, 255).chr + g.clamp(0, 255).chr + b.clamp(0, 255).chr
|
514
|
-
end
|
515
|
-
|
516
|
-
def self.decode_etc2_block(bin)
|
517
|
-
if bin[33] == 0
|
518
|
-
# individual
|
519
|
-
colors = [0, 0]
|
520
|
-
colors[0] = bin >> 40 & 0xf0f0f0
|
521
|
-
colors[0] = colors[0] | colors[0] >> 4
|
522
|
-
colors[1] = bin >> 36 & 0xf0f0f0
|
523
|
-
colors[1] = colors[1] | colors[1] >> 4
|
524
|
-
codes = [bin >> 37 & 7, bin >> 34 & 7]
|
525
|
-
subblocks = Etc1SubblockTable[bin[32]]
|
526
|
-
(0...16).map do |i|
|
527
|
-
modifier = Etc1ModifierTable[codes[subblocks[i]]][bin[i]]
|
528
|
-
etc1colormod(colors[subblocks[i]], bin[i + 16] == 0 ? modifier : -modifier)
|
529
|
-
end
|
530
|
-
else
|
531
|
-
r = bin >> 59
|
532
|
-
dr = (bin >> 56 & 3) - (bin >> 56 & 4)
|
533
|
-
g = bin >> 51 & 0x1f
|
534
|
-
dg = (bin >> 48 & 3) - (bin >> 48 & 4)
|
535
|
-
b = bin >> 43 & 0x1f
|
536
|
-
db = (bin >> 40 & 3) - (bin >> 40 & 4)
|
537
|
-
if r + dr < 0 || r + dr > 31
|
538
|
-
# T mode
|
539
|
-
base1 = (bin >> 49 & 0xc00) | (bin >> 48 & 0x3ff)
|
540
|
-
base1 = (base1 & 0xf00) << 8 | (base1 & 0xf0) << 4 | (base1 & 0xf)
|
541
|
-
base1 = (base1 << 4) | base1
|
542
|
-
base2 = bin >> 36 & 0xfff
|
543
|
-
base2 = (base2 & 0xf00) << 8 | (base2 & 0xf0) << 4 | (base2 & 0xf)
|
544
|
-
base2 = (base2 << 4) | base2
|
545
|
-
d = Etc2DistanceTable[(bin >> 33 & 6) + bin[32]]
|
546
|
-
colors = [[base1].pack('N')[1,3], etc1colormod(base2, d), [base2].pack('N')[1,3], etc1colormod(base2, -d)]
|
547
|
-
(0...16).map{|i| colors[bin[i] + bin[i + 16] * 2]}
|
548
|
-
elsif g + dg < 0 || g + dg > 31
|
549
|
-
# H mode
|
550
|
-
base1 = (bin >> 51 & 0xfe0) | (bin >> 48 & 0x18) | (bin >> 47 & 7)
|
551
|
-
base1 = (base1 & 0xf00) << 8 | (base1 & 0xf0) << 4 | (base1 & 0xf)
|
552
|
-
base1 = (base1 << 4) | base1
|
553
|
-
base2 = bin >> 35 & 0xfff
|
554
|
-
base2 = (base2 & 0xf00) << 8 | (base2 & 0xf0) << 4 | (base2 & 0xf)
|
555
|
-
base2 = (base2 << 4) | base2
|
556
|
-
d = Etc2DistanceTable[bin[34] * 2 + bin[32]]
|
557
|
-
colors = [etc1colormod(base1, d), etc1colormod(base1, -d), etc1colormod(base2, d), etc1colormod(base2, -d)]
|
558
|
-
(0...16).map{|i| colors[bin[i] + bin[i + 16] * 2]}
|
559
|
-
elsif b + db < 0 || b + db > 31
|
560
|
-
# planar mode
|
561
|
-
color_or = (bin >> 55 & 0xfc) | (bin >> 61 & 0x03)
|
562
|
-
color_og = (bin >> 49 & 0x80) | (bin >> 48 & 0x7e) | bin[56]
|
563
|
-
color_ob = (bin >> 41 & 0x80) | (bin >> 38 & 0x60) | (bin >> 37 & 0x1c) | (bin >> 47 & 2) | bin[44]
|
564
|
-
color_hr = (bin >> 31 & 0xf8) | (bin >> 30 & 0x04) | (bin >> 37 & 0x03)
|
565
|
-
color_hg = (bin >> 24 & 0xfe) | bin[31]
|
566
|
-
color_hb = (bin >> 17 & 0xfc) | (bin >> 23 & 0x03)
|
567
|
-
color_vr = (bin >> 11 & 0xfc) | (bin >> 17 & 0x03)
|
568
|
-
color_vg = (bin >> 5 & 0xfe) | bin[12]
|
569
|
-
color_vb = (bin << 2 & 0xfc) | (bin >> 4 & 0x03)
|
570
|
-
(0...16).map do |i|
|
571
|
-
x = i / 4
|
572
|
-
y = i % 4
|
573
|
-
r = (x * (color_hr - color_or) + y * (color_vr - color_or) + 4 * color_or + 2) >> 2
|
574
|
-
g = (x * (color_hg - color_og) + y * (color_vg - color_og) + 4 * color_og + 2) >> 2
|
575
|
-
b = (x * (color_hb - color_ob) + y * (color_vb - color_ob) + 4 * color_ob + 2) >> 2
|
576
|
-
r.clamp(0, 255).chr + g.clamp(0, 255).chr + b.clamp(0, 255).chr
|
577
|
-
end
|
578
|
-
else
|
579
|
-
# differential mode
|
580
|
-
colors = [0, 0]
|
581
|
-
colors[0] = bin >> 40 & 0xf8f8f8
|
582
|
-
colors[1] = colors[0] + (dr << 19) + (dg << 11) + (db << 3)
|
583
|
-
colors[0] = colors[0] | (colors[0] >> 5 & 0x70707)
|
584
|
-
colors[1] = colors[1] | (colors[1] >> 5 & 0x70707)
|
585
|
-
codes = [bin >> 37 & 7, bin >> 34 & 7]
|
586
|
-
subblocks = Etc1SubblockTable[bin[32]]
|
587
|
-
(0...16).map do |i|
|
588
|
-
modifier = Etc1ModifierTable[codes[subblocks[i]]][bin[i]]
|
589
|
-
etc1colormod(colors[subblocks[i]], bin[i + 16] == 0 ? modifier : -modifier)
|
590
|
-
end
|
591
|
-
end
|
592
|
-
end
|
593
|
-
end
|
594
|
-
|
595
|
-
def self.decode_etc2alpha_block(bin)
|
596
|
-
if bin & 0xf0000000000000 == 0
|
597
|
-
Array.new(16, (bin >> 56).chr)
|
598
|
-
else
|
599
|
-
base = bin >> 56
|
600
|
-
mult = bin >> 52 & 0xf
|
601
|
-
table = Etc2AlphaModTable[bin >> 48 & 0xf]
|
602
|
-
(0...16).map{|i| (base + table[bin >> i*3 & 7] * mult).clamp(0, 255).chr}
|
603
|
-
end
|
604
|
-
end
|
605
|
-
|
606
445
|
# convert 16bit float
|
607
446
|
def self.n2f(n)
|
608
447
|
case n
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|