69 lines
1.9 KiB
Python
69 lines
1.9 KiB
Python
import struct
|
|
import time
|
|
import zlib
|
|
|
|
ITEX_MAGIC = 0x58455449
|
|
ITEX_VERSION = 1
|
|
ITEX_HEADER_SIZE = 56
|
|
ITEX_STRUCT = struct.Struct("<IHHIIIIIIIIIHHII")
|
|
|
|
def load_itex_from_bytes(data, base_off=0):
|
|
if len(data) < base_off + ITEX_HEADER_SIZE:
|
|
raise ValueError("ITEX: too small")
|
|
|
|
(
|
|
magic,
|
|
version,
|
|
header_size,
|
|
width,
|
|
height,
|
|
channels,
|
|
is_float,
|
|
has_alpha,
|
|
has_smooth_alpha,
|
|
uncompressed_size,
|
|
compressed_size,
|
|
handle_value,
|
|
handle_type,
|
|
handle_meta,
|
|
reserved0,
|
|
reserved1
|
|
) = ITEX_STRUCT.unpack_from(data, base_off)
|
|
|
|
if magic != ITEX_MAGIC or version != ITEX_VERSION or header_size != ITEX_HEADER_SIZE:
|
|
raise ValueError("ITEX: bad header")
|
|
|
|
if width == 0 or height == 0 or channels == 0:
|
|
raise ValueError("ITEX: bad dims")
|
|
|
|
if compressed_size == 0 or uncompressed_size == 0:
|
|
raise ValueError("ITEX: bad sizes")
|
|
|
|
payload_off = base_off + header_size
|
|
end = payload_off + compressed_size
|
|
if end > len(data):
|
|
raise ValueError("ITEX: truncated payload")
|
|
|
|
comp = data[payload_off:end]
|
|
t0 = time.perf_counter()
|
|
pixels = zlib.decompress(comp)
|
|
t1 = time.perf_counter()
|
|
|
|
if len(pixels) != uncompressed_size:
|
|
raise ValueError("ITEX: decompressed size mismatch")
|
|
|
|
h = (int(handle_value) & 0xFFFFFFFF, int(handle_type) & 0xFFFF, int(handle_meta) & 0xFFFF)
|
|
info = {
|
|
"width": int(width),
|
|
"height": int(height),
|
|
"channels": int(channels),
|
|
"is_float": int(is_float),
|
|
"has_alpha": int(has_alpha),
|
|
"has_smooth_alpha": int(has_smooth_alpha),
|
|
"compressed_size": int(compressed_size),
|
|
"decompressed_size": int(uncompressed_size),
|
|
"decompress_ms": (t1 - t0) * 1000.0,
|
|
"decode_offset": int(base_off),
|
|
}
|
|
return h, info, pixels
|