using System; using System.IO; using UnityEngine; // Filename : CBitImage.cs // Creator : ported from C++ (AutoPFImp/AutoMoveImp/bitimage.h) // Date : 2026/01/09 namespace AutoMove { /// /// Bit image used by AutoPF (passable map). /// 自动寻路使用的位图(可通行图)。 /// public class CBitImage { // Current Version // 当前版本 private const uint BITIMAGE_VER = 0x00000003; // old version // 旧版本 private const uint BITIMAGE_OLD_VER = 0x00000001; // magic // 魔数 // C++: (DWORD)(('b'<<24)| ('m'<<16)|('p'<<8)|('f')) => bytes: 'f''p''m''b' in LE. private const uint BITIMAGE_MAGIC = 0x626D7066; // width of the bit image (in chars) // 位图宽(按字节) private int m_iWidth; // length of the bit image (in chars) // 位图长(按字节) private int m_iLength; // pixel size // 像素尺寸 private float m_fPixelSize; // width of the bit image ( in pixels) // 位图宽(像素) private int m_iImageWidth; // length of the bit image ( in pixels) // 位图长(像素) private int m_iImageLength; // raw bit image bytes // 位图原始字节 private byte[] m_BitImage; public void Release() { m_BitImage = null; m_iWidth = 0; m_iLength = 0; m_iImageWidth = 0; m_iImageLength = 0; m_fPixelSize = 1.0f; } public void GetImageSize(out int width, out int length) { width = m_iImageWidth; length = m_iImageLength; } public float GetPixelSize() => m_fPixelSize; public bool GetPixel(int u, int v) { if (m_BitImage == null) return false; if (u < 0 || u >= m_iImageWidth || v < 0 || v >= m_iImageLength) return false; int uInChar = u >> 3; int shift = u & 0x7; return (m_BitImage[v * m_iWidth + uInChar] & (1 << shift)) != 0; } /// /// Load from file bytes (binary). Supports old and magic formats like original C++. /// 从文件字节加载(二进制)。支持原版 C++ 的旧版和带 magic 版本。 /// public bool Load(byte[] fileBytes) { try { if (fileBytes == null || fileBytes.Length < 8) return false; using var ms = new MemoryStream(fileBytes, false); using var br = new BinaryReader(ms); uint flag = br.ReadUInt32(); if (flag == BITIMAGE_OLD_VER) { // old: proceed to BufSize // 旧版:直接读取 BufSize } else if (flag == BITIMAGE_MAGIC) { // magic then version // magic 后面跟版本号 uint ver = br.ReadUInt32(); if (ver > BITIMAGE_VER) { return false; } } else { return false; } uint bufSize = br.ReadUInt32(); if (bufSize == 0 || bufSize > fileBytes.Length) return false; byte[] buf = br.ReadBytes((int)bufSize); if (buf.Length != bufSize) return false; int cur = 0; m_iWidth = BitConverter.ToInt32(buf, cur); cur += 4; m_iLength = BitConverter.ToInt32(buf, cur); cur += 4; m_iImageWidth = BitConverter.ToInt32(buf, cur); cur += 4; m_iImageLength = BitConverter.ToInt32(buf, cur); cur += 4; m_fPixelSize = BitConverter.ToSingle(buf, cur); cur += 4; int imgSize = m_iWidth * m_iLength; if (imgSize <= 0) return false; if (cur + imgSize > buf.Length) return false; m_BitImage = new byte[imgSize]; Buffer.BlockCopy(buf, cur, m_BitImage, 0, imgSize); return true; } catch (Exception ex) { Debug.LogWarning($"[CBitImage] Load failed: {ex.Message}"); return false; } } } }