tool class_name AImgIOCRC32 extends Resource # CRC32 implementation that uses a Resource for better caching const INIT = 0xFFFFFFFF # The reversed polynomial. export var reversed_polynomial: int = 0xEDB88320 # The mask (and initialization value). export var mask: int = 0xFFFFFFFF var crc32_table = [] var _table_init_mutex: Mutex = Mutex.new() var _table_initialized: bool = false # Ensures the CRC32's cached part is ready. # Should be called very infrequently, definitely not in an inner loop. func ensure_ready(): _table_init_mutex.lock() if not _table_initialized: # Calculate CRC32 table. var range8 := range(8) for i in range(256): var crc := i for j in range8: if (crc & 1) != 0: crc = (crc >> 1) ^ reversed_polynomial else: crc >>= 1 crc32_table.push_back(crc & mask) _table_initialized = true _table_init_mutex.unlock() # Performs the update step of CRC32 over some bytes. # Note that this is not the whole story. # The CRC must be initialized to 0xFFFFFFFF, then updated, then bitwise-inverted. func update(crc: int, data: PoolByteArray) -> int: var i := 0 var l := len(data) while i < l: var lb := data[i] ^ (crc & 0xFF) crc = crc32_table[lb] ^ (crc >> 8) i += 1 return crc # Finishes the CRC by XORing it with the mask. func end(crc: int) -> int: return crc ^ mask