public override async Task ReadDomainObject(ByteArrayReader reader, DomainHeader header, DomainExportTableEntry export, bool skipProperties, bool skipParse) { await base.ReadDomainObject(reader, header, export, skipProperties, skipParse); if (skipParse) { return; } MipMapsCount = reader.ReadInt32(); for (int i = 0; i < MipMapsCount; ++i) { await ProcessCompressedBulkData(reader, async bulkChunk => { DomainMipMap mip = new DomainMipMap { Width = reader.ReadInt32(), Height = reader.ReadInt32() }; if (mip.Width >= 4 || mip.Height >= 4) { mip.ImageData = (await bulkChunk.DecompressChunk(0))?.GetBytes(); } MipMaps.Add(mip); }); } Guid = await reader.ReadBytes(16); }
public PNG(BaseImage image) { Width = image.Width; Height = image.Height; foreach (MipMap mipmap in image.MipMaps) { MipMaps.Add(new MipMap(mipmap)); } }
private void PreprocessMipMaps() { bool hwCompressed = Format == TextureContentFormat.DXT1 || Format == TextureContentFormat.DXT3 || Format == TextureContentFormat.DXT5; int width = Width, height = Height; int realCount = 0; for (int i = 0; i < (GenerateMipMaps ? 1 : MipMapCount); i++) { if (hwCompressed) { int dataSize = 0; byte[] data = null; ThreadingHelper.BlockOnUIThread(() => { GL.BindTexture(TextureTarget.Texture2D, texture); GL.GetTexLevelParameter(TextureTarget.Texture2D, i, GetTextureParameter.TextureCompressedImageSize, out dataSize); data = new byte[dataSize]; GL.GetCompressedTexImage(TextureTarget.Texture2D, i, data); }); MipMaps.Add(new TextureContentMipMap(width, height, Format, data)); } else { var bmp = new System.Drawing.Bitmap(width, height); var bmpData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); ThreadingHelper.BlockOnUIThread(() => { GL.BindTexture(TextureTarget.Texture2D, texture); GL.GetTexImage(TextureTarget.Texture2D, i, OpenTK.Graphics.OpenGL4.PixelFormat.Bgra, PixelType.UnsignedByte, bmpData.Scan0); }); bmp.UnlockBits(bmpData); MipMaps.Add(new TextureContentMipMap(width, height, Format, bmp)); } width /= 2; height /= 2; realCount++; if (width == 0 || height == 0) { break; } } if (!GenerateMipMaps) { MipMapCount = realCount; } }
private void GetFromBitmap(Bitmap bitmap) { Bitmap bmp = new Bitmap(bitmap); Width = bmp.Width; Height = bmp.Height; MipMap mipMap = new MipMap(Width, Height); for (int y = 0; y < Height; y++) { for (int x = 0; x < Width; x++) { Color col = bmp.GetPixel(x, y); int index = (y * Width + x) * 4; mipMap.Pixels[index] = col.B; mipMap.Pixels[index + 1] = col.G; mipMap.Pixels[index + 2] = col.R; mipMap.Pixels[index + 3] = col.A; } } MipMaps.Add(mipMap); }
protected override void _Read(BinaryReader reader) { Image image = Image.FromStream(reader.BaseStream); Bitmap bmp = new Bitmap(image); Width = bmp.Width; Height = bmp.Height; MipMap mipMap = new MipMap(Width, Height); for (int y = 0; y < Height; y++) { for (int x = 0; x < Width; x++) { Color col = bmp.GetPixel(x, y); int index = (y * Width + x) * 4; mipMap.Pixels[index] = col.B; mipMap.Pixels[index + 1] = col.G; mipMap.Pixels[index + 2] = col.R; mipMap.Pixels[index + 3] = col.A; } } MipMaps.Add(mipMap); }
public override async Task SetObject(string filename, List <DomainNameTableEntry> nameTable) { ImageEngineImage image = await Task.Run(() => new ImageEngineImage(filename)); int width = image.Width; int height = image.Height; DomainPropertyIntValue sizeX = PropertyHeader.GetProperty("SizeX").FirstOrDefault()?.Value as DomainPropertyIntValue; DomainPropertyIntValue sizeY = PropertyHeader.GetProperty("SizeY").FirstOrDefault()?.Value as DomainPropertyIntValue; sizeX?.SetPropertyValue(width); sizeY?.SetPropertyValue(height); DomainPropertyIntValue mipTailBaseIdx = PropertyHeader.GetProperty("MipTailBaseIdx").FirstOrDefault()?.Value as DomainPropertyIntValue; mipTailBaseIdx?.SetPropertyValue((int)Math.Log(width > height ? width : height, 2)); DomainPropertyStringValue filePath = PropertyHeader.GetProperty("SourceFilePath").FirstOrDefault()?.Value as DomainPropertyStringValue; DomainPropertyStringValue fileTime = PropertyHeader.GetProperty("SourceFileTimestamp").FirstOrDefault()?.Value as DomainPropertyStringValue; filePath?.SetPropertyValue(filename); fileTime?.SetPropertyValue(File.GetLastWriteTime(filename).ToString("yyyy-MM-dd hh:mm:ss")); DomainPropertyByteValue pfFormat = PropertyHeader.GetProperty("Format").FirstOrDefault()?.Value as DomainPropertyByteValue; ImageEngineFormat imageFormat = image.Format.InternalFormat; if (!imageFormat.ToString().Contains("DDS")) { throw new Exception($"Image is not in a DDS format. It is actually {imageFormat}."); } if (pfFormat != null) { string formatStr = imageFormat.ToString().Replace("DDS", "PF"); if (formatStr.Contains("ARGB")) { formatStr = "PF_A8R8G8B8"; } else if (formatStr.Contains("G8")) { formatStr = "PF_G8"; } DomainNameTableEntry formatTableEntry = nameTable.SingleOrDefault(nt => nt.Name.String == formatStr) ?? nameTable.AddDomainNameTableEntry(formatStr); pfFormat.SetPropertyValue(formatTableEntry); } MipMaps.Clear(); while (true) { MemoryStream stream = new MemoryStream(); image.Save(stream, imageFormat, MipHandling.KeepTopOnly); await stream.FlushAsync(); MipMaps.Add(new DomainMipMap { ImageData = (await ByteArrayReader.CreateNew(stream.ToArray(), 0x80).Splice()).GetBytes(), // Strip off 128 bytes for the DDS header Width = image.Width, Height = image.Height }); if (width == 1 && height == 1) { break; } if (width > 1) { width /= 2; } if (height > 1) { height /= 2; } if (image.Width > 4 && image.Height > 4) { image.Resize(0.5, false); } } }
public override async Task SetObject(string filename, List <DomainNameTableEntry> nameTable, object configuration) { DdsSaveConfig config = configuration as DdsSaveConfig ?? new DdsSaveConfig(FileFormat.Unknown, 0, 0, false, false); DdsFile image = await Task.Run(() => new DdsFile(filename)); bool skipFirstMip = false; int width = image.Width; int height = image.Height; if (MipMaps[0].ImageData == null || MipMaps[0].ImageData.Length == 0) { width *= 2; height *= 2; skipFirstMip = true; } DomainPropertyIntValue sizeX = PropertyHeader.GetProperty("SizeX").FirstOrDefault()?.Value as DomainPropertyIntValue; DomainPropertyIntValue sizeY = PropertyHeader.GetProperty("SizeY").FirstOrDefault()?.Value as DomainPropertyIntValue; sizeX?.SetPropertyValue(skipFirstMip ? width * 2 : width); sizeY?.SetPropertyValue(skipFirstMip ? height * 2 : height); DomainPropertyIntValue mipTailBaseIdx = PropertyHeader.GetProperty("MipTailBaseIdx").FirstOrDefault()?.Value as DomainPropertyIntValue; int indexSize = width > height ? width : height; mipTailBaseIdx?.SetPropertyValue((int)Math.Log(skipFirstMip ? indexSize * 2 : indexSize, 2)); DomainPropertyStringValue filePath = PropertyHeader.GetProperty("SourceFilePath").FirstOrDefault()?.Value as DomainPropertyStringValue; DomainPropertyStringValue fileTime = PropertyHeader.GetProperty("SourceFileTimestamp").FirstOrDefault()?.Value as DomainPropertyStringValue; filePath?.SetPropertyValue(filename); fileTime?.SetPropertyValue(File.GetLastWriteTime(filename).ToString("yyyy-MM-dd hh:mm:ss")); DomainPropertyByteValue pfFormat = PropertyHeader.GetProperty("Format").FirstOrDefault()?.Value as DomainPropertyByteValue; FileFormat imageFormat = FileFormat.Unknown; if (pfFormat != null) { imageFormat = DdsPixelFormat.ParseFileFormat(pfFormat.PropertyString); } if (imageFormat == FileFormat.Unknown) { throw new Exception($"Unknown DDS File Format ({pfFormat?.PropertyString ?? "Unknown"})."); } config.FileFormat = imageFormat; MipMaps.Clear(); if (skipFirstMip) { MipMaps.Add(new DomainMipMap { ImageData = null, Width = width, Height = height }); } image.GenerateMipMaps(4, 4); foreach (DdsMipMap mipMap in image.MipMaps.OrderByDescending(mip => mip.Width)) { MipMaps.Add(new DomainMipMap { ImageData = image.WriteMipMap(mipMap, config), Width = mipMap.Width, Height = mipMap.Height }); } }
public DDS(D3DFormat format, Bitmap bitmap) { SquishFlags flags = SquishFlags.kDxt1; bool compressed = true; switch (format) { case D3DFormat.DXT1: flags = SquishFlags.kDxt1; break; case D3DFormat.DXT3: flags = SquishFlags.kDxt3; break; case D3DFormat.DXT5: flags = SquishFlags.kDxt5; break; default: compressed = false; break; } Format = format; Width = bitmap.Width; Height = bitmap.Height; MipMap mip = new MipMap { Width = Width, Height = Height }; byte[] data = new byte[mip.Width * mip.Height * 4]; BitmapData bmpdata = bitmap.LockBits(new Rectangle(0, 0, mip.Width, mip.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); Marshal.Copy(bmpdata.Scan0, data, 0, bmpdata.Stride * bmpdata.Height); bitmap.UnlockBits(bmpdata); if (compressed) { for (uint i = 0; i < data.Length - 4; i += 4) { byte r = data[i + 0]; data[i + 0] = data[i + 2]; data[i + 2] = r; } byte[] dest = new byte[Squish.Squish.GetStorageRequirements(mip.Width, mip.Height, flags | SquishFlags.kColourIterativeClusterFit)]; Squish.Squish.CompressImage(data, mip.Width, mip.Height, ref dest, flags | SquishFlags.kColourIterativeClusterFit); mip.Data = dest; } else { mip.Data = data; } MipMaps.Add(mip); }