do block state unpacking with numpy slices, not loops
For posterity, my testbench used to make sure this implementation yields identical results: https://gist.github.com/agrif/a34efb8e0b534f0309415c9af4872a69
This commit is contained in:
@@ -961,91 +961,66 @@ class RegionSet(object):
|
|||||||
if bits_per_value < 4 or 12 < bits_per_value:
|
if bits_per_value < 4 or 12 < bits_per_value:
|
||||||
raise nbt.CorruptChunkError()
|
raise nbt.CorruptChunkError()
|
||||||
b = numpy.frombuffer(numpy.asarray(long_array, dtype=numpy.uint64), dtype=numpy.uint8)
|
b = numpy.frombuffer(numpy.asarray(long_array, dtype=numpy.uint64), dtype=numpy.uint8)
|
||||||
|
# give room for work, later
|
||||||
|
b = b.astype(numpy.uint16)
|
||||||
if bits_per_value == 8:
|
if bits_per_value == 8:
|
||||||
result = b.astype(numpy.uint16)
|
return b
|
||||||
else:
|
|
||||||
result = []
|
result = numpy.zeros((n,), dtype=numpy.uint16)
|
||||||
i = 0
|
|
||||||
# We will consume the byte array in chunks equal to bits_per_value.
|
|
||||||
while i < len(b):
|
|
||||||
if bits_per_value == 4:
|
if bits_per_value == 4:
|
||||||
for k in range(0, 4):
|
result[0::2] = b & 0x0f
|
||||||
result.extend([
|
result[1::2] = (b & 0xf0) >> 4
|
||||||
b[i + k] & 0x0f,
|
|
||||||
(b[i + k] & 0xf0) >> 4,
|
|
||||||
])
|
|
||||||
i += 4
|
|
||||||
elif bits_per_value == 5:
|
elif bits_per_value == 5:
|
||||||
result.extend([
|
result[0::8] = b[0::5] & 0x1f
|
||||||
b[i] & 0x1f,
|
result[1::8] = ((b[1::5] & 0x03) << 3) | ((b[0::5] & 0xe0) >> 5)
|
||||||
((b[i+1] & 0x03) << 3) | ((b[i] & 0xe0) >> 5),
|
result[2::8] = (b[1::5] & 0x7c) >> 2
|
||||||
(b[i+1] & 0x7c) >> 2,
|
result[3::8] = ((b[2::5] & 0x0f) << 1) | ((b[1::5] & 0x80) >> 7)
|
||||||
((b[i+2] & 0x0f) << 1) | ((b[i+1] & 0x80) >> 7),
|
result[4::8] = ((b[3::5] & 0x01) << 4) | ((b[2::5] & 0xf0) >> 4)
|
||||||
((b[i+3] & 0x01) << 4) | ((b[i+2] & 0xf0) >> 4),
|
result[5::8] = (b[3::5] & 0x3e) >> 1
|
||||||
(b[i+3] & 0x3e) >> 1,
|
result[6::8] = ((b[4::5] & 0x07) << 2) | ((b[3::5] & 0xc0) >> 6)
|
||||||
((b[i+4] & 0x07) << 2) | ((b[i+3] & 0xc0) >> 6),
|
result[7::8] = (b[4::5] & 0xf8) >> 3
|
||||||
(b[i+4] & 0xf8) >> 3,
|
|
||||||
])
|
|
||||||
i += 5
|
|
||||||
elif bits_per_value == 6:
|
elif bits_per_value == 6:
|
||||||
result.extend([
|
result[0::4] = b[0::3] & 0x3f
|
||||||
b[i] & 0x3f,
|
result[1::4] = ((b[1::3] & 0x0f) << 2) | ((b[0::3] & 0xc0) >> 6)
|
||||||
((b[i+1] & 0x0f) << 2) | ((b[i] & 0xc0) >> 6),
|
result[2::4] = ((b[2::3] & 0x03) << 4) | ((b[1::3] & 0xf0) >> 4)
|
||||||
((b[i+2] & 0x03) << 4) | ((b[i+1] & 0xf0) >> 4),
|
result[3::4] = (b[2::3] & 0xfc) >> 2
|
||||||
(b[i+2] & 0xfc) >> 2,
|
|
||||||
])
|
|
||||||
i += 3
|
|
||||||
elif bits_per_value == 7:
|
elif bits_per_value == 7:
|
||||||
result.extend([
|
result[0::8] = b[0::7] & 0x7f
|
||||||
b[i] & 0x7f,
|
result[1::8] = ((b[1::7] & 0x3f) << 1) | ((b[0::7] & 0x80) >> 7)
|
||||||
((b[i+1] & 0x3f) << 1) | ((b[i] & 0x80) >> 7),
|
result[2::8] = ((b[2::7] & 0x1f) << 2) | ((b[1::7] & 0xc0) >> 6)
|
||||||
((b[i+2] & 0x1f) << 2) | ((b[i+1] & 0xc0) >> 6),
|
result[3::8] = ((b[3::7] & 0x0f) << 3) | ((b[2::7] & 0xe0) >> 5)
|
||||||
((b[i+3] & 0x0f) << 3) | ((b[i+2] & 0xe0) >> 5),
|
result[4::8] = ((b[4::7] & 0x07) << 4) | ((b[3::7] & 0xf0) >> 4)
|
||||||
((b[i+4] & 0x07) << 4) | ((b[i+3] & 0xf0) >> 4),
|
result[5::8] = ((b[5::7] & 0x03) << 5) | ((b[4::7] & 0xf8) >> 3)
|
||||||
((b[i+5] & 0x03) << 5) | ((b[i+4] & 0xf8) >> 3),
|
result[6::8] = ((b[6::7] & 0x01) << 6) | ((b[5::7] & 0xfc) >> 2)
|
||||||
((b[i+6] & 0x01) << 6) | ((b[i+5] & 0xfc) >> 2),
|
result[7::8] = (b[6::7] & 0xfc) >> 1
|
||||||
(b[i+6] & 0xfc) >> 1,
|
# bits_per_value == 8 is handled above
|
||||||
])
|
|
||||||
i += 7
|
|
||||||
elif bits_per_value == 9:
|
elif bits_per_value == 9:
|
||||||
result.extend([
|
result[0::8] = ((b[1::9] & 0x01) << 8) | b[0::9]
|
||||||
((b[i+1] & 0x01) << 8) | b[i],
|
result[1::8] = ((b[2::9] & 0x03) << 7) | ((b[1::9] & 0xfe) >> 1)
|
||||||
((b[i+2] & 0x03) << 7) | ((b[i+1] & 0xfe) >> 1),
|
result[2::8] = ((b[3::9] & 0x07) << 6) | ((b[2::9] & 0xfc) >> 2)
|
||||||
((b[i+3] & 0x07) << 6) | ((b[i+2] & 0xfc) >> 2),
|
result[3::8] = ((b[4::9] & 0x0f) << 5) | ((b[3::9] & 0xf8) >> 3)
|
||||||
((b[i+4] & 0x0f) << 5) | ((b[i+3] & 0xf8) >> 3),
|
result[4::8] = ((b[5::9] & 0x1f) << 4) | ((b[4::9] & 0xf0) >> 4)
|
||||||
((b[i+5] & 0x1f) << 4) | ((b[i+4] & 0xf0) >> 4),
|
result[5::8] = ((b[6::9] & 0x3f) << 3) | ((b[5::9] & 0xe0) >> 5)
|
||||||
((b[i+6] & 0x3f) << 3) | ((b[i+5] & 0xe0) >> 5),
|
result[6::8] = ((b[7::9] & 0x7f) << 2) | ((b[6::9] & 0xc0) >> 6)
|
||||||
((b[i+7] & 0x7f) << 2) | ((b[i+6] & 0xc0) >> 6),
|
result[7::8] = ( b[8::9] << 1) | ((b[7::9] & 0x80) >> 7)
|
||||||
(b[i+8] << 1) | ((b[i+7] & 0x80) >> 7),
|
|
||||||
])
|
|
||||||
i += 9
|
|
||||||
elif bits_per_value == 10:
|
elif bits_per_value == 10:
|
||||||
result.extend([
|
result[0::4] = ((b[1::5] & 0x03) << 8) | b[0::5]
|
||||||
((b[i+1] & 0x03) << 8) | b[i],
|
result[1::4] = ((b[2::5] & 0x0f) << 6) | ((b[1::5] & 0xfc) >> 2)
|
||||||
((b[i+2] & 0x0f) << 6) | ((b[i+1] & 0xfc) >> 2),
|
result[2::4] = ((b[3::5] & 0x3f) << 4) | ((b[2::5] & 0xf0) >> 4)
|
||||||
((b[i+3] & 0x3f) << 4) | ((b[i+2] & 0xf0) >> 4),
|
result[3::4] = ( b[4::5] << 2) | ((b[3::5] & 0xc0) >> 6)
|
||||||
(b[i+4] << 2) | ((b[i+3] & 0xc0) >> 6),
|
|
||||||
])
|
|
||||||
i += 5
|
|
||||||
elif bits_per_value == 11:
|
elif bits_per_value == 11:
|
||||||
result.extend([
|
result[0::8] = ((b[ 1::11] & 0x07) << 8 ) | b[ 0::11]
|
||||||
((b[i+1] & 0x07) << 8) | b[i],
|
result[1::8] = ((b[ 2::11] & 0x3f) << 5 ) | ((b[ 1::11] & 0xf8) >> 3 )
|
||||||
((b[i+2] & 0x3f) << 5) | ((b[i+1] & 0xf8) >> 3),
|
result[2::8] = ((b[ 4::11] & 0x01) << 10) | ( b[ 3::11] << 2 ) | ((b[ 2::11] & 0xc0) >> 6 )
|
||||||
((b[i+4] & 0x01) << 10)| (b[i+3] << 2) | ((b[i+2] & 0xc0) >> 6),
|
result[3::8] = ((b[ 5::11] & 0x0f) << 7 ) | ((b[ 4::11] & 0xfe) >> 1 )
|
||||||
((b[i+5] & 0x0f) << 7) | ((b[i+4] & 0xfe) >> 1),
|
result[4::8] = ((b[ 6::11] & 0x7f) << 4 ) | ((b[ 5::11] & 0xf0) >> 4 )
|
||||||
((b[i+6] & 0x7f) << 4) | ((b[i+5] & 0xf0) >> 4),
|
result[5::8] = ((b[ 8::11] & 0x03) << 9 ) | ( b[ 7::11] << 1 ) | ((b[ 6::11] & 0x80) >> 7 )
|
||||||
((b[i+8] & 0x03) << 9) | (b[i+7] << 1) | ((b[i+6] & 0x80) >> 7),
|
result[6::8] = ((b[ 9::11] & 0x1f) << 2 ) | ((b[ 8::11] & 0xfc) >> 2 )
|
||||||
((b[i+9] & 0x1f) << 2) | ((b[i+8] & 0xfc) >> 2),
|
result[7::8] = ( b[10::11] << 3 ) | ((b[ 9::11] & 0xe0) >> 5 )
|
||||||
(b[i+10] << 3) | ((b[i+9] & 0xe0) >> 5),
|
|
||||||
])
|
|
||||||
i += 11
|
|
||||||
elif bits_per_value == 12:
|
elif bits_per_value == 12:
|
||||||
result.extend([
|
result[0::2] = ((b[1::3] & 0x0f) << 8) | b[0::3]
|
||||||
((b[i+1] & 0x0f) << 8) | b[i],
|
result[1::2] = ( b[2::3] << 4) | ((b[1::3] & 0xf0) >> 4)
|
||||||
(b[i+2] << 4) | ((b[i+1] & 0xf0) >> 4),
|
|
||||||
])
|
|
||||||
i += 3
|
|
||||||
result = numpy.asarray(result, numpy.uint16)
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _get_blockdata_v113(self, section, unrecognized_block_types):
|
def _get_blockdata_v113(self, section, unrecognized_block_types):
|
||||||
|
|||||||
Reference in New Issue
Block a user