protected virtual Bitmap GetImageResource(F4ImageResourceHeader imageHeader) { if (imageHeader == null) { return(null); } var palette = new ushort[imageHeader.PaletteSize]; for (var i = 0; i < palette.Length; i++) { palette[i] = BitConverter.ToUInt16(_resourceIndex.ResourceData.Data, (int)imageHeader.PaletteOffset + (i * 2)); } var pixelFormat = (((imageHeader.Flags & (uint)F4ResourceFlags.EightBit) == (uint)F4ResourceFlags.EightBit)) ? PixelFormat.Format8bppIndexed : PixelFormat.Format16bppRgb555; var bytesPerPixel = (((imageHeader.Flags & (uint)F4ResourceFlags.EightBit) == (uint)F4ResourceFlags.EightBit)) ? 1 : 2; var toReturn = new Bitmap(imageHeader.Width, imageHeader.Height, pixelFormat); var lockBits = toReturn.LockBits(new Rectangle(0, 0, imageHeader.Width, imageHeader.Height), ImageLockMode.WriteOnly, pixelFormat); try { var stride = lockBits.Stride; for (var y = 0; y < imageHeader.Height; y++) { Marshal.Copy(_resourceIndex.ResourceData.Data, (int)imageHeader.ImageOffset + (y * imageHeader.Width * bytesPerPixel), IntPtr.Add(lockBits.Scan0, y * stride), imageHeader.Width * bytesPerPixel); } } finally { toReturn.UnlockBits(lockBits); } if (((imageHeader.Flags & (uint)F4ResourceFlags.EightBit) == (uint)F4ResourceFlags.EightBit)) { var colorPalette = toReturn.Palette; for (var i = 0; i < palette.Length; i++) { var A = 255; var R = ((palette[i] & 0x7C00) >> 10) << 3; var G = ((palette[i] & 0x3E0) >> 5) << 3; var B = (palette[i] & 0x1F) << 3; colorPalette.Entries[i] = Color.FromArgb(A, R, G, B); } toReturn.Palette = colorPalette; } return(toReturn); }
public virtual void Load(string resourceBundleIndexPath) { var resourceIndexFileInfo = new FileInfo(resourceBundleIndexPath); if (resourceIndexFileInfo.Exists) { var bytes = new byte[resourceIndexFileInfo.Length]; using (var fs = new FileStream(resourceBundleIndexPath, FileMode.Open, FileAccess.Read)) { fs.Seek(0, SeekOrigin.Begin); fs.Read(bytes, 0, (int)resourceIndexFileInfo.Length); } _resourceIndex = new F4ResourceBundleIndex(); var curByte = 0; _resourceIndex.Size = BitConverter.ToUInt32(bytes, curByte); curByte += 4; _resourceIndex.ResourceIndexVersion = BitConverter.ToUInt32(bytes, curByte); curByte += 4; var size = _resourceIndex.Size; var headers = new List <F4ResourceHeader>(); while (size > 0) { _resourceIndex.NumResources++; var resourceType = BitConverter.ToUInt32(bytes, curByte); curByte += 4; var resourceId = new byte[32]; for (var j = 0; j < 32; j++) { resourceId[j] = bytes[curByte]; curByte++; } var resourceName = Encoding.ASCII.GetString(resourceId); var nullLoc = resourceName.IndexOf('\0'); resourceName = nullLoc > 0 ? resourceName.Substring(0, nullLoc) : null; if (resourceType == (uint)(ResourceType.ImageResource)) { var thisResourceHeader = new F4ImageResourceHeader { Type = resourceType, ID = resourceName, Flags = BitConverter.ToUInt32(bytes, curByte) }; curByte += 4; thisResourceHeader.CenterX = BitConverter.ToUInt16(bytes, curByte); curByte += 2; thisResourceHeader.CenterY = BitConverter.ToUInt16(bytes, curByte); curByte += 2; thisResourceHeader.Width = BitConverter.ToUInt16(bytes, curByte); curByte += 2; thisResourceHeader.Height = BitConverter.ToUInt16(bytes, curByte); curByte += 2; thisResourceHeader.ImageOffset = BitConverter.ToUInt32(bytes, curByte); curByte += 4; thisResourceHeader.PaletteSize = BitConverter.ToUInt32(bytes, curByte); curByte += 4; thisResourceHeader.PaletteOffset = BitConverter.ToUInt32(bytes, curByte); curByte += 4; headers.Add(thisResourceHeader); size -= 60; } else if (resourceType == (uint)(ResourceType.SoundResource)) { var thisResourceHeader = new F4SoundResourceHeader { Type = resourceType, ID = resourceName, Flags = BitConverter.ToUInt32(bytes, curByte) }; curByte += 4; thisResourceHeader.Channels = BitConverter.ToUInt16(bytes, curByte); curByte += 2; thisResourceHeader.SoundType = BitConverter.ToUInt16(bytes, curByte); curByte += 2; thisResourceHeader.Offset = BitConverter.ToUInt32(bytes, curByte); curByte += 4; thisResourceHeader.HeaderSize = BitConverter.ToUInt32(bytes, curByte); curByte += 4; headers.Add(thisResourceHeader); size -= 52; } else if (resourceType == (uint)(ResourceType.FlatResource)) { var thisResourceHeader = new F4FlatResourceHeader { Type = resourceType, ID = resourceName, Offset = BitConverter.ToUInt32(bytes, curByte) }; curByte += 4; thisResourceHeader.Size = BitConverter.ToUInt32(bytes, curByte); curByte += 4; headers.Add(thisResourceHeader); size -= 44; } } _resourceIndex.ResourceHeaders = headers.ToArray(); var resourceDataFileInfo = new FileInfo( Path.GetDirectoryName(resourceIndexFileInfo.FullName) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(resourceIndexFileInfo.FullName) + RESOURCE_FILE_EXTENSION); if (resourceDataFileInfo.Exists) { bytes = new byte[resourceDataFileInfo.Length]; using (var fs = new FileStream(resourceDataFileInfo.FullName, FileMode.Open, FileAccess.Read)) { fs.Seek(0, SeekOrigin.Begin); fs.Read(bytes, 0, (int)resourceDataFileInfo.Length); } var rawDataPackage = new F4ResourceRawDataPackage(); curByte = 0; rawDataPackage.Size = BitConverter.ToUInt32(bytes, curByte); curByte += 4; rawDataPackage.Version = BitConverter.ToUInt32(bytes, curByte); curByte += 4; rawDataPackage.Data = new byte[rawDataPackage.Size]; var numBytesToCopy = Math.Min(rawDataPackage.Data.Length, bytes.Length - curByte); Array.Copy(bytes, curByte, rawDataPackage.Data, 0, numBytesToCopy); curByte += numBytesToCopy; _resourceIndex.ResourceData = rawDataPackage; } else { throw new FileNotFoundException(resourceDataFileInfo.FullName); } } else { throw new FileNotFoundException(resourceBundleIndexPath); } }