/// <summary> /// Calculate how many bytes of data certain mip map level should take /// </summary> /// <param name="pixelFormat">Pixel format</param> /// <param name="width">Width</param> /// <param name="height">Height</param> /// <returns>Amount of bytes needed for mipmap level</returns> public static int CalculateBytesOfData(PixelFormatV3 pixelFormat, int width, int height) { if (pixelFormat == PixelFormatV3.PVRTC2bppRGB || pixelFormat == PixelFormatV3.PVRTC2bppRGBA) { return(width * height / 4); } else if (pixelFormat == PixelFormatV3.PVRTC4bppRGB || pixelFormat == PixelFormatV3.PVRTC4bppRGBA) { return(width * height / 2); } throw new NotImplementedException(); }
/// <summary> /// Constructor for PVR header V3 /// </summary> /// <param name="inputBytes">Input byte array</param> public PVRHeaderV3(byte[] inputBytes) { int currentIndex = 0; uint endianness = BitConverter.ToUInt32(inputBytes, currentIndex); bool swapEndianness = false; if (endianness == matchingEndianness) { } else if (endianness == notMatchingEndianness) { swapEndianness = true; } else { throw new ArgumentException($"Incorrect endian value {endianness}"); } currentIndex += 4; uint textureFlagsUint = BitConverter.ToUInt32(inputBytes, currentIndex); if (Enum.IsDefined(typeof(TextureFlags), textureFlagsUint)) { this.textureFlags = (TextureFlags)textureFlagsUint; } else { throw new ArgumentException($"Incorrect flags value {textureFlagsUint}"); } currentIndex += 4; ulong pixelFormatUlong = BitConverter.ToUInt64(inputBytes, currentIndex); if (Enum.IsDefined(typeof(PixelFormatV3), pixelFormatUlong)) { this.pixelFormat = (PixelFormatV3)pixelFormatUlong; } else { throw new ArgumentException($"Incorrect pixel format value {pixelFormatUlong}"); } currentIndex += 8; uint colorSpaceUint = BitConverter.ToUInt32(inputBytes, currentIndex); if (Enum.IsDefined(typeof(ColorSpace), colorSpaceUint)) { this.colorSpace = (ColorSpace)colorSpaceUint; } else { throw new ArgumentException($"Incorrect color space value {colorSpaceUint}"); } currentIndex += 4; uint channelTypeUint = BitConverter.ToUInt32(inputBytes, currentIndex); if (Enum.IsDefined(typeof(ChannelType), channelTypeUint)) { this.channelType = (ChannelType)channelTypeUint; } else { throw new ArgumentException($"Incorrect channel type value {channelTypeUint}"); } currentIndex += 4; this.height = BitConverter.ToUInt32(inputBytes, currentIndex); currentIndex += 4; this.width = BitConverter.ToUInt32(inputBytes, currentIndex); currentIndex += 4; this.depth = BitConverter.ToUInt32(inputBytes, currentIndex); currentIndex += 4; this.numSurfaces = BitConverter.ToUInt32(inputBytes, currentIndex); currentIndex += 4; this.numFaces = BitConverter.ToUInt32(inputBytes, currentIndex); currentIndex += 4; this.mipMapCount = BitConverter.ToUInt32(inputBytes, currentIndex); currentIndex += 4; this.metaDataSizeInBytes = BitConverter.ToUInt32(inputBytes, currentIndex); }
/// <summary> /// Constructor for PVR header V3 /// </summary> /// <param name="inputStream">Input stream</param> public PVRHeaderV3(Stream inputStream) { if (inputStream == null) { throw new NullReferenceException("inputStream is null"); } if (!inputStream.CanRead) { throw new ArgumentException("inputStream must be readable"); } using (BinaryReader reader = new BinaryReader(inputStream, System.Text.Encoding.UTF8, leaveOpen: true)) { uint endianness = reader.ReadUInt32(); bool swapEndianness = false; if (endianness == matchingEndianness) { } else if (endianness == notMatchingEndianness) { swapEndianness = true; } else { throw new ArgumentException($"Incorrect endian value {endianness}"); } uint textureFlagsUint = reader.ReadUInt32(); if (Enum.IsDefined(typeof(TextureFlags), textureFlagsUint)) { this.textureFlags = (TextureFlags)textureFlagsUint; } else { throw new ArgumentException($"Incorrect flags value {textureFlagsUint}"); } ulong pixelFormatUlong = reader.ReadUInt64(); if (Enum.IsDefined(typeof(PixelFormatV3), pixelFormatUlong)) { this.pixelFormat = (PixelFormatV3)pixelFormatUlong; } else { throw new ArgumentException($"Incorrect pixel format value {pixelFormatUlong}"); } uint colorSpaceUint = reader.ReadUInt32(); if (Enum.IsDefined(typeof(ColorSpace), colorSpaceUint)) { this.colorSpace = (ColorSpace)colorSpaceUint; } else { throw new ArgumentException($"Incorrect color space value {colorSpaceUint}"); } uint channelTypeUint = reader.ReadUInt32(); if (Enum.IsDefined(typeof(ChannelType), channelTypeUint)) { this.channelType = (ChannelType)channelTypeUint; } else { throw new ArgumentException($"Incorrect channel type value {channelTypeUint}"); } this.height = reader.ReadUInt32(); this.width = reader.ReadUInt32(); this.depth = reader.ReadUInt32(); this.numSurfaces = reader.ReadUInt32(); this.numFaces = reader.ReadUInt32(); this.mipMapCount = reader.ReadUInt32(); this.metaDataSizeInBytes = reader.ReadUInt32(); } }