using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Runtime.InteropServices; using UnityEngine; public class TimFile { public enum Format : byte { Bpp4Bit = 0, Bpp8Bit = 1, Bpp16Bit = 2, Bpp24Bit = 3 } [Serializable] [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct Header { public uint h1; public uint h2; public byte Tag { get { return (byte)(h1 & 0xff); } } public byte Version { get { return (byte)((h1 >> 8) & 0xff); } } public Format Format { get { return (Format)(h2 & 0x3); } } public bool ColorLutPresent { get { return (h2 & 0x08) != 0; } } } [Serializable] [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct ImageBlockHeader { public uint length; public ushort x; public ushort y; public ushort width; public ushort height; } public class ImageBlock { public ImageBlockHeader header; public ushort[] data; } public Header header; public ImageBlock lut; public ImageBlock image; public int ImageWidth { get { switch (header.Format) { case Format.Bpp4Bit: return image.header.width * 4; case Format.Bpp8Bit: return image.header.width * 2; case Format.Bpp16Bit: return image.header.width * 1; case Format.Bpp24Bit: return (int)(image.header.width / 1.5f); default: return image.header.width; } } } public int ImageHeight { get { return image.header.height; } } private static ImageBlock ReadImageBlock(BinaryReader reader) { ImageBlock result = new ImageBlock(); result.header.length = reader.ReadUInt32(); result.header.x = reader.ReadUInt16(); result.header.y = reader.ReadUInt16(); result.header.width = reader.ReadUInt16(); result.header.height = reader.ReadUInt16(); var dataSize = result.header.length - 12; result.data = new ushort[dataSize / 2]; for (int i = 0; i < result.data.Length; ++i) { result.data[i] = reader.ReadUInt16(); } return result; } public static TimFile Parse(byte[] data) { TimFile result = new TimFile(); MemoryStream src = new MemoryStream(data); BinaryReader r = new BinaryReader(src); result.header.h1 = r.ReadUInt32(); result.header.h2 = r.ReadUInt32(); if (result.header.ColorLutPresent) { result.lut = ReadImageBlock(r); } result.image = ReadImageBlock(r); return result; } }