private static Bitmap LoadImage(BinaryReader br, uint width, uint height, VtfImageFormat format) { var buffer = new byte[width * height * 4]; switch (format) { case VtfImageFormat.Rgba8888: TransformBytes(buffer, br, width, height, 4, 3, 0, 1, 2, false); break; case VtfImageFormat.Abgr8888: TransformBytes(buffer, br, width, height, 4, 0, 3, 2, 1, false); break; case VtfImageFormat.Rgb888: TransformBytes(buffer, br, width, height, 3, -1, 0, 1, 2, false); break; case VtfImageFormat.Bgr888: TransformBytes(buffer, br, width, height, 3, -1, 2, 1, 0, false); break; case VtfImageFormat.Rgb565: throw new NotImplementedException(); break; case VtfImageFormat.I8: throw new NotImplementedException(); break; case VtfImageFormat.Ia88: throw new NotImplementedException(); break; case VtfImageFormat.P8: throw new NotImplementedException(); break; case VtfImageFormat.A8: throw new NotImplementedException(); break; case VtfImageFormat.Rgb888Bluescreen: TransformBytes(buffer, br, width, height, 3, -1, 0, 1, 2, true); break; case VtfImageFormat.Bgr888Bluescreen: TransformBytes(buffer, br, width, height, 3, -1, 2, 1, 0, true); break; case VtfImageFormat.Argb8888: TransformBytes(buffer, br, width, height, 4, 0, 1, 2, 3, false); break; case VtfImageFormat.Bgra8888: br.Read(buffer, 0, buffer.Length); break; case VtfImageFormat.Dxt1: case VtfImageFormat.Dxt1Onebitalpha: DecompressDxt1(buffer, br, width, height); break; case VtfImageFormat.Dxt3: throw new NotImplementedException(); break; case VtfImageFormat.Dxt5: DecompressDxt5(buffer, br, width, height); break; case VtfImageFormat.Bgrx8888: TransformBytes(buffer, br, width, height, 4, -1, 2, 1, 0, false); break; case VtfImageFormat.Bgr565: throw new NotImplementedException(); break; case VtfImageFormat.Bgrx5551: throw new NotImplementedException(); break; case VtfImageFormat.Bgra4444: throw new NotImplementedException(); break; case VtfImageFormat.Bgra5551: throw new NotImplementedException(); break; case VtfImageFormat.Uv88: TransformBytes(buffer, br, width, height, 2, -1, 0, 1, -1, false); break; case VtfImageFormat.Uvwq8888: throw new NotImplementedException(); break; case VtfImageFormat.Rgba16161616F: TransformRgba16161616F(buffer, br, width, height); break; case VtfImageFormat.Rgba16161616: TransformShorts(buffer, br, width, height, 8, 3, 0, 1, 2); break; case VtfImageFormat.Uvlx8888: throw new NotImplementedException(); break; case VtfImageFormat.R32F: throw new NotImplementedException(); break; case VtfImageFormat.Rgb323232F: throw new NotImplementedException(); break; case VtfImageFormat.Rgba32323232F: throw new NotImplementedException(); break; case VtfImageFormat.NvDst16: throw new NotImplementedException(); break; case VtfImageFormat.NvDst24: throw new NotImplementedException(); break; case VtfImageFormat.NvIntz: throw new NotImplementedException(); break; case VtfImageFormat.NvRawz: throw new NotImplementedException(); break; case VtfImageFormat.AtiDst16: throw new NotImplementedException(); break; case VtfImageFormat.AtiDst24: throw new NotImplementedException(); break; case VtfImageFormat.NvNull: throw new NotImplementedException(); break; case VtfImageFormat.Ati2N: throw new NotImplementedException(); break; case VtfImageFormat.Ati1N: throw new NotImplementedException(); break; } var bmp = new Bitmap((int)width, (int)height, PixelFormat.Format32bppArgb); var bits = bmp.LockBits(new Rectangle(0, 0, (int)width, (int)height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); Marshal.Copy(buffer, 0, bits.Scan0, buffer.Length); bmp.UnlockBits(bits); return bmp; }
private static uint ComputeImageSize(uint width, uint height, uint depth, VtfImageFormat imageFormat) { switch (imageFormat) { case VtfImageFormat.Dxt1: case VtfImageFormat.Dxt1Onebitalpha: if (width < 4 && width > 0) { width = 4; } if (height < 4 && height > 0) { height = 4; } return(((width + 3) / 4) * ((height + 3) / 4) * 8 * depth); case VtfImageFormat.Dxt3: case VtfImageFormat.Dxt5: if (width < 4 && width > 0) { width = 4; } if (height < 4 && height > 0) { height = 4; } return(((width + 3) / 4) * ((height + 3) / 4) * 16 * depth); default: return(width * height * depth * GetImageFormatInfo(imageFormat).BytesPerPixel); } }
public VtfImageFormatInfo(VtfImageFormat format, uint bitsPerPixel, uint bytesPerPixel, uint redBitsPerPixel, uint greenBitsPerPixel, uint blueBitsPerPixel, uint alphaBitsPerPixel, bool isCompressed, bool isSupported) { Format = format; BitsPerPixel = bitsPerPixel; BytesPerPixel = bytesPerPixel; RedBitsPerPixel = redBitsPerPixel; GreenBitsPerPixel = greenBitsPerPixel; BlueBitsPerPixel = blueBitsPerPixel; AlphaBitsPerPixel = alphaBitsPerPixel; IsCompressed = isCompressed; IsSupported = isSupported; }
private static uint ComputeMipmapSize(int width, int height, int depth, int mipLevel, VtfImageFormat format) { var w = MipmapResize(width, mipLevel); var h = MipmapResize(height, mipLevel); var d = MipmapResize(depth, mipLevel); return ComputeImageSize((uint) w, (uint) h, (uint) d, format); }
private static uint ComputeImageSize(uint width, uint height, uint depth, uint uiMipmaps, VtfImageFormat imageFormat) { uint uiImageSize = 0; for (var i = 0; i < uiMipmaps; i++) { uiImageSize += ComputeImageSize(width, height, depth, imageFormat); width >>= 1; height >>= 1; depth >>= 1; if (width < 1) width = 1; if (height < 1) height = 1; if (depth < 1) depth = 1; } return uiImageSize; }
private static uint ComputeImageSize(uint width, uint height, uint depth, VtfImageFormat imageFormat) { switch (imageFormat) { case VtfImageFormat.Dxt1: case VtfImageFormat.Dxt1Onebitalpha: if (width < 4 && width > 0) width = 4; if (height < 4 && height > 0) height = 4; return ((width + 3) / 4) * ((height + 3) / 4) * 8 * depth; case VtfImageFormat.Dxt3: case VtfImageFormat.Dxt5: if (width < 4 && width > 0) width = 4; if (height < 4 && height > 0) height = 4; return ((width + 3) / 4) * ((height + 3) / 4) * 16 * depth; default: return width * height * depth * GetImageFormatInfo(imageFormat).BytesPerPixel; } }
private VtfImageFormatInfo( VtfImageFormat format, int bitsPerPixel, int bytesPerPixel, int redBitsPerPixel, int greenBitsPerPixel, int blueBitsPerPixel, int alphaBitsPerPixel, int redIndex, int greenIndex, int blueIndex, int alphaIndex, bool isCompressed, bool isSupported, TransformPixel pixelTransform = null ) { Format = format; BitsPerPixel = bitsPerPixel; BytesPerPixel = bytesPerPixel; RedBitsPerPixel = redBitsPerPixel; GreenBitsPerPixel = greenBitsPerPixel; BlueBitsPerPixel = blueBitsPerPixel; AlphaBitsPerPixel = alphaBitsPerPixel; RedIndex = redIndex; GreenIndex = greenIndex; BlueIndex = blueIndex; AlphaIndex = alphaIndex; IsCompressed = isCompressed; IsSupported = isSupported; _pixelTransform = pixelTransform; _is8Aligned = (redBitsPerPixel == 0 || redBitsPerPixel == 8) && (greenBitsPerPixel == 0 || greenBitsPerPixel == 8) && (blueBitsPerPixel == 0 || blueBitsPerPixel == 8) && (alphaBitsPerPixel == 0 || alphaBitsPerPixel == 8); _is16Aligned = (redBitsPerPixel == 0 || redBitsPerPixel == 16) && (greenBitsPerPixel == 0 || greenBitsPerPixel == 16) && (blueBitsPerPixel == 0 || blueBitsPerPixel == 16) && (alphaBitsPerPixel == 0 || alphaBitsPerPixel == 16); _is32Aligned = (redBitsPerPixel == 0 || redBitsPerPixel == 32) && (greenBitsPerPixel == 0 || greenBitsPerPixel == 32) && (blueBitsPerPixel == 0 || blueBitsPerPixel == 32) && (alphaBitsPerPixel == 0 || alphaBitsPerPixel == 32); if (!_is8Aligned && !_is16Aligned && !_is32Aligned) { var masks = new[] { new Mask('r', redBitsPerPixel, redIndex), new Mask('g', greenBitsPerPixel, greenIndex), new Mask('b', blueBitsPerPixel, blueIndex), new Mask('a', alphaBitsPerPixel, alphaIndex), }.OrderBy(x => x.Index).ToList(); var offset = bitsPerPixel; foreach (var m in masks) { offset -= m.Size; m.Offset = offset; } var dict = masks.ToDictionary(x => x.Component, x => x); _masks = new[] { dict['b'], dict['g'], dict['r'], dict['a'] }; } }
public VtfFile(Stream stream) { Header = new VtfHeader(); Resources = new List <VtfResource>(); Images = new List <VtfImage>(); using (BinaryReader br = new BinaryReader(stream)) { string header = br.ReadFixedLengthString(Encoding.ASCII, 4); if (header != VtfHeader) { throw new Exception("Invalid VTF header. Expected '" + VtfHeader + "', got '" + header + "'."); } uint v1 = br.ReadUInt32(); uint v2 = br.ReadUInt32(); decimal version = v1 + (v2 / 10m); // e.g. 7.3 Header.Version = version; uint headerSize = br.ReadUInt32(); ushort width = br.ReadUInt16(); ushort height = br.ReadUInt16(); Header.Flags = (VtfImageFlag)br.ReadUInt32(); ushort numFrames = br.ReadUInt16(); ushort firstFrame = br.ReadUInt16(); br.ReadBytes(4); // padding Header.Reflectivity = br.ReadVector3(); br.ReadBytes(4); // padding Header.BumpmapScale = br.ReadSingle(); VtfImageFormat highResImageFormat = (VtfImageFormat)br.ReadUInt32(); byte mipmapCount = br.ReadByte(); VtfImageFormat lowResImageFormat = (VtfImageFormat)br.ReadUInt32(); byte lowResWidth = br.ReadByte(); byte lowResHeight = br.ReadByte(); ushort depth = 1; uint numResources = 0; if (version >= 7.2m) { depth = br.ReadUInt16(); } if (version >= 7.3m) { br.ReadBytes(3); numResources = br.ReadUInt32(); br.ReadBytes(8); } int faces = 1; if (Header.Flags.HasFlag(VtfImageFlag.Envmap)) { faces = version < 7.5m && firstFrame != 0xFFFF ? 7 : 6; } VtfImageFormatInfo highResFormatInfo = VtfImageFormatInfo.FromFormat(highResImageFormat); VtfImageFormatInfo lowResFormatInfo = VtfImageFormatInfo.FromFormat(lowResImageFormat); int thumbnailSize = lowResImageFormat == VtfImageFormat.None ? 0 : lowResFormatInfo.GetSize(lowResWidth, lowResHeight); uint thumbnailPos = headerSize; long dataPos = headerSize + thumbnailSize; for (int i = 0; i < numResources; i++) { VtfResourceType type = (VtfResourceType)br.ReadUInt32(); uint data = br.ReadUInt32(); switch (type) { case VtfResourceType.LowResImage: // Low res image thumbnailPos = data; break; case VtfResourceType.Image: // Regular image dataPos = data; break; case VtfResourceType.Sheet: case VtfResourceType.Crc: case VtfResourceType.TextureLodSettings: case VtfResourceType.TextureSettingsEx: case VtfResourceType.KeyValueData: // todo Resources.Add(new VtfResource { Type = type, Data = data }); break; default: throw new ArgumentOutOfRangeException(nameof(type), (uint)type, "Unknown resource type"); } } if (lowResImageFormat != VtfImageFormat.None) { br.BaseStream.Position = thumbnailPos; int thumbSize = lowResFormatInfo.GetSize(lowResWidth, lowResHeight); LowResImage = new VtfImage { Format = lowResImageFormat, Width = lowResWidth, Height = lowResHeight, Data = br.ReadBytes(thumbSize) }; } br.BaseStream.Position = dataPos; for (int mip = mipmapCount - 1; mip >= 0; mip--) { for (int frame = 0; frame < numFrames; frame++) { for (int face = 0; face < faces; face++) { for (int slice = 0; slice < depth; slice++) { int wid = GetMipSize(width, mip); int hei = GetMipSize(height, mip); int size = highResFormatInfo.GetSize(wid, hei); Images.Add(new VtfImage { Format = highResImageFormat, Width = wid, Height = hei, Mipmap = mip, Frame = frame, Face = face, Slice = slice, Data = br.ReadBytes(size) }); } } } } } }
private static Texture2D LoadImage(BinaryReader br, uint width, uint height, VtfImageFormat format, bool remipmap) { var buffer = new byte[width * height * 4]; switch (format) { case VtfImageFormat.Rgba8888: TransformBytes(buffer, br, width, height, 4, 3, 0, 1, 2, false); break; case VtfImageFormat.Abgr8888: TransformBytes(buffer, br, width, height, 4, 0, 3, 2, 1, false); break; case VtfImageFormat.Rgb888: TransformBytes(buffer, br, width, height, 3, -1, 0, 1, 2, false); break; case VtfImageFormat.Bgr888: TransformBytes(buffer, br, width, height, 3, -1, 2, 1, 0, false); break; case VtfImageFormat.Rgb565: throw new NotImplementedException(); case VtfImageFormat.I8: throw new NotImplementedException(); case VtfImageFormat.Ia88: throw new NotImplementedException(); case VtfImageFormat.P8: throw new NotImplementedException(); case VtfImageFormat.A8: throw new NotImplementedException(); case VtfImageFormat.Rgb888Bluescreen: TransformBytes(buffer, br, width, height, 3, -1, 0, 1, 2, true); break; case VtfImageFormat.Bgr888Bluescreen: TransformBytes(buffer, br, width, height, 3, -1, 2, 1, 0, true); break; case VtfImageFormat.Argb8888: TransformBytes(buffer, br, width, height, 4, 0, 1, 2, 3, false); break; case VtfImageFormat.Bgra8888: br.Read(buffer, 0, buffer.Length); break; case VtfImageFormat.Dxt1: case VtfImageFormat.Dxt1Onebitalpha: DecompressDxt1(buffer, br, width, height); break; case VtfImageFormat.Dxt3: throw new NotImplementedException(); case VtfImageFormat.Dxt5: DecompressDxt5(buffer, br, width, height); break; case VtfImageFormat.Bgrx8888: TransformBytes(buffer, br, width, height, 4, -1, 2, 1, 0, false); break; case VtfImageFormat.Bgr565: throw new NotImplementedException(); case VtfImageFormat.Bgrx5551: throw new NotImplementedException(); case VtfImageFormat.Bgra4444: throw new NotImplementedException(); case VtfImageFormat.Bgra5551: throw new NotImplementedException(); case VtfImageFormat.Uv88: TransformBytes(buffer, br, width, height, 2, -1, 0, 1, -1, false); break; case VtfImageFormat.Uvwq8888: throw new NotImplementedException(); case VtfImageFormat.Rgba16161616F: TransformRgba16161616F(buffer, br, width, height); break; case VtfImageFormat.Rgba16161616: TransformShorts(buffer, br, width, height, 8, 3, 0, 1, 2); break; case VtfImageFormat.Uvlx8888: throw new NotImplementedException(); case VtfImageFormat.R32F: throw new NotImplementedException(); case VtfImageFormat.Rgb323232F: throw new NotImplementedException(); case VtfImageFormat.Rgba32323232F: throw new NotImplementedException(); case VtfImageFormat.NvDst16: throw new NotImplementedException(); case VtfImageFormat.NvDst24: throw new NotImplementedException(); case VtfImageFormat.NvIntz: throw new NotImplementedException(); case VtfImageFormat.NvRawz: throw new NotImplementedException(); case VtfImageFormat.AtiDst16: throw new NotImplementedException(); case VtfImageFormat.AtiDst24: throw new NotImplementedException(); case VtfImageFormat.NvNull: throw new NotImplementedException(); case VtfImageFormat.Ati2N: throw new NotImplementedException(); case VtfImageFormat.Ati1N: throw new NotImplementedException(); } var result = new Texture2D((int)width, (int)height, TextureFormat.BGRA32, false); result.LoadRawTextureData(buffer); if (remipmap) { Color32[] tempCol = result.GetPixels32(); //for(int i = 0; i < tempCol.Length; i++) //{ // tempCol[i] = ((Color)tempCol[i]).gamma; //} result = new Texture2D((int)width, (int)height, TextureFormat.BGRA32, true); result.SetPixels32(tempCol); result.Apply(true); result.Compress(true); } result.Apply(); return(result); }
private static long GetImageDataLocation(int frame, int face, int slice, int mip, VtfImageFormat format, int width, int height, int numFrames, int numFaces, int depth, int numMips) { long offset = 0; // Transverse past all frames and faces of each mipmap (up to the requested one). for (var i = numMips - 1; i > mip; i--) { offset += ComputeMipmapSize(width, height, depth, i, format) * numFrames * numFaces; } var uiTemp1 = ComputeMipmapSize(width, height, depth, mip, format); var uiTemp2 = ComputeMipmapSize(width, height, 1, mip, format); // Transverse past requested frames and faces of requested mipmap. offset += uiTemp1 * frame * numFaces * depth; offset += uiTemp1 * face * depth; offset += uiTemp2 * slice; return(offset); }
private static uint ComputeMipmapSize(int width, int height, int depth, int mipLevel, VtfImageFormat format) { var w = MipmapResize(width, mipLevel); var h = MipmapResize(height, mipLevel); var d = MipmapResize(depth, mipLevel); return(ComputeImageSize((uint)w, (uint)h, (uint)d, format)); }
private static VtfImageFormatInfo GetImageFormatInfo(VtfImageFormat imageFormat) { return(ImageFormats[imageFormat]); }
private static uint ComputeImageSize(uint width, uint height, uint depth, uint uiMipmaps, VtfImageFormat imageFormat) { uint uiImageSize = 0; for (var i = 0; i < uiMipmaps; i++) { uiImageSize += ComputeImageSize(width, height, depth, imageFormat); width >>= 1; height >>= 1; depth >>= 1; if (width < 1) { width = 1; } if (height < 1) { height = 1; } if (depth < 1) { depth = 1; } } return(uiImageSize); }
public static VtfImageFormatInfo FromFormat(VtfImageFormat imageFormat) => ImageFormats[imageFormat];
private static Bitmap LoadImage(BinaryReader br, uint width, uint height, VtfImageFormat format) { var buffer = new byte[width * height * 4]; switch (format) { case VtfImageFormat.Rgba8888: TransformBytes(buffer, br, width, height, 4, 3, 0, 1, 2, false); break; case VtfImageFormat.Abgr8888: TransformBytes(buffer, br, width, height, 4, 0, 3, 2, 1, false); break; case VtfImageFormat.Rgb888: TransformBytes(buffer, br, width, height, 3, -1, 0, 1, 2, false); break; case VtfImageFormat.Bgr888: TransformBytes(buffer, br, width, height, 3, -1, 2, 1, 0, false); break; case VtfImageFormat.Rgb565: throw new NotImplementedException(); break; case VtfImageFormat.I8: throw new NotImplementedException(); break; case VtfImageFormat.Ia88: throw new NotImplementedException(); break; case VtfImageFormat.P8: throw new NotImplementedException(); break; case VtfImageFormat.A8: throw new NotImplementedException(); break; case VtfImageFormat.Rgb888Bluescreen: TransformBytes(buffer, br, width, height, 3, -1, 0, 1, 2, true); break; case VtfImageFormat.Bgr888Bluescreen: TransformBytes(buffer, br, width, height, 3, -1, 2, 1, 0, true); break; case VtfImageFormat.Argb8888: TransformBytes(buffer, br, width, height, 4, 0, 1, 2, 3, false); break; case VtfImageFormat.Bgra8888: br.Read(buffer, 0, buffer.Length); break; case VtfImageFormat.Dxt1: case VtfImageFormat.Dxt1Onebitalpha: DecompressDxt1(buffer, br, width, height); break; case VtfImageFormat.Dxt3: throw new NotImplementedException(); break; case VtfImageFormat.Dxt5: DecompressDxt5(buffer, br, width, height); break; case VtfImageFormat.Bgrx8888: TransformBytes(buffer, br, width, height, 4, -1, 2, 1, 0, false); break; case VtfImageFormat.Bgr565: throw new NotImplementedException(); break; case VtfImageFormat.Bgrx5551: throw new NotImplementedException(); break; case VtfImageFormat.Bgra4444: throw new NotImplementedException(); break; case VtfImageFormat.Bgra5551: throw new NotImplementedException(); break; case VtfImageFormat.Uv88: TransformBytes(buffer, br, width, height, 2, -1, 0, 1, -1, false); break; case VtfImageFormat.Uvwq8888: throw new NotImplementedException(); break; case VtfImageFormat.Rgba16161616F: TransformRgba16161616F(buffer, br, width, height); break; case VtfImageFormat.Rgba16161616: TransformShorts(buffer, br, width, height, 8, 3, 0, 1, 2); break; case VtfImageFormat.Uvlx8888: throw new NotImplementedException(); break; case VtfImageFormat.R32F: throw new NotImplementedException(); break; case VtfImageFormat.Rgb323232F: throw new NotImplementedException(); break; case VtfImageFormat.Rgba32323232F: throw new NotImplementedException(); break; case VtfImageFormat.NvDst16: throw new NotImplementedException(); break; case VtfImageFormat.NvDst24: throw new NotImplementedException(); break; case VtfImageFormat.NvIntz: throw new NotImplementedException(); break; case VtfImageFormat.NvRawz: throw new NotImplementedException(); break; case VtfImageFormat.AtiDst16: throw new NotImplementedException(); break; case VtfImageFormat.AtiDst24: throw new NotImplementedException(); break; case VtfImageFormat.NvNull: throw new NotImplementedException(); break; case VtfImageFormat.Ati2N: throw new NotImplementedException(); break; case VtfImageFormat.Ati1N: throw new NotImplementedException(); break; } var bmp = new Bitmap((int)width, (int)height, PixelFormat.Format32bppArgb); var bits = bmp.LockBits(new Rectangle(0, 0, (int)width, (int)height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); Marshal.Copy(buffer, 0, bits.Scan0, buffer.Length); bmp.UnlockBits(bits); return(bmp); }
private static long GetImageDataLocation(int frame, int face, int slice, int mip, VtfImageFormat format, int width, int height, int numFrames, int numFaces, int depth, int numMips) { long offset = 0; // Transverse past all frames and faces of each mipmap (up to the requested one). for (var i = numMips - 1; i > mip; i--) { offset += ComputeMipmapSize(width, height, depth, i, format) * numFrames * numFaces; } var uiTemp1 = ComputeMipmapSize(width, height, depth, mip, format); var uiTemp2 = ComputeMipmapSize(width, height, 1, mip, format); // Transverse past requested frames and faces of requested mipmap. offset += uiTemp1 * frame * numFaces * depth; offset += uiTemp1 * face * depth; offset += uiTemp2 * slice; return offset; }
private static VtfImageFormatInfo GetImageFormatInfo(VtfImageFormat imageFormat) { return ImageFormats[imageFormat]; }