Exemplo n.º 1
0
        /// <summary>
        /// Determines if this is a SVR texture.
        /// </summary>
        /// <param name="source">Byte array containing the data.</param>
        /// <param name="offset">The offset in the byte array to start at.</param>
        /// <param name="length">Length of the data (in bytes).</param>
        /// <returns>True if this is a SVR texture, false otherwise.</returns>
        public static bool Is(byte[] source, int offset, int length)
        {
            // GBIX and PVRT
            if (length >= 0x20 &&
                PTMethods.Contains(source, offset + 0x00, Encoding.UTF8.GetBytes("GBIX")) &&
                PTMethods.Contains(source, offset + 0x10, Encoding.UTF8.GetBytes("PVRT")) &&
                source[offset + 0x19] >= 0x60 && source[offset + 0x19] < 0x70)
            {
                // Some SVR files have an extra byte at the end for seemingly no reason.
                UInt32 expected_length = BitConverter.ToUInt32(source, offset + 0x14);
                if (expected_length == length - 24 || expected_length == length - 24 - 1)
                {
                    return(true);
                }
            }

            // PVRT (and no GBIX chunk)
            else if (length >= 0x10 &&
                     PTMethods.Contains(source, offset + 0x00, Encoding.UTF8.GetBytes("PVRT")) &&
                     source[offset + 0x09] >= 0x60 && source[offset + 0x09] < 0x70)
            {
                // Some SVR files have an extra byte at the end for seemingly no reason.
                UInt32 expected_length = BitConverter.ToUInt32(source, offset + 0x04);
                if (expected_length == length - 8 || expected_length == length - 8 - 1)
                {
                    return(true);
                }
            }

            return(false);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Determines if this is a GVR texture.
        /// </summary>
        /// <param name="source">Byte array containing the data.</param>
        /// <param name="offset">The offset in the byte array to start at.</param>
        /// <param name="length">Length of the data (in bytes).</param>
        /// <returns>True if this is a GVR texture, false otherwise.</returns>
        public static bool Is(byte[] source, int offset, int length)
        {
            // GBIX and GVRT
            if (length >= 32 &&
                PTMethods.Contains(source, offset + 0x00, Encoding.UTF8.GetBytes("GBIX")) &&
                PTMethods.Contains(source, offset + 0x10, Encoding.UTF8.GetBytes("GVRT")) &&
                BitConverter.ToUInt32(source, offset + 0x14) == length - 24)
            {
                return(true);
            }

            // GCIX and GVRT
            else if (length >= 32 &&
                     PTMethods.Contains(source, offset + 0x00, Encoding.UTF8.GetBytes("GCIX")) &&
                     PTMethods.Contains(source, offset + 0x10, Encoding.UTF8.GetBytes("GVRT")) &&
                     BitConverter.ToUInt32(source, offset + 0x14) == length - 24)
            {
                return(true);
            }

            // GVRT (and no GBIX or GCIX chunk)
            else if (length > 16 &&
                     PTMethods.Contains(source, offset + 0x00, Encoding.UTF8.GetBytes("GVRT")) &&
                     BitConverter.ToUInt32(source, offset + 0x04) == length - 8)
            {
                return(true);
            }

            return(false);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Determines if this is a PVP palette.
        /// </summary>
        /// <param name="source">Byte array containing the data.</param>
        /// <param name="offset">The offset in the byte array to start at.</param>
        /// <param name="length">Length of the data (in bytes).</param>
        /// <returns>True if this is a PVP palette, false otherwise.</returns>
        public static bool Is(byte[] source, int offset, int length)
        {
            if (length >= 16 &&
                PTMethods.Contains(source, offset + 0x00, Encoding.UTF8.GetBytes("PVPL")) &&
                BitConverter.ToUInt32(source, offset + 0x04) == length - 8)
            {
                return(true);
            }

            return(false);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Checks for and validates GBIX headers as well as PVRT.
        /// <para>See also: <seealso cref="IsValidPvrt"/></para>
        /// </summary>
        /// <param name="source">Byte array containing the data.</param>
        /// <param name="offset">The offset in the byte array to start at.</param>
        /// <param name="length">The expected length of the data minus the preceding header sizes.</param>
        /// <returns>True if the header is GBIX and it passes validation, false otherwise.</returns>
        private static bool IsValidGbix(byte[] source, int offset, int length)
        {
            if (!PTMethods.Contains(source, offset, gbixFourCC))
            {
                return(false);
            }

            // Immediately after the "GBIX" part of the GBIX header, there is
            // an offset indicating where the PVRT header begins relative to 0x08.
            int pvrtOffset = PTMethods.ToInt32(source, offset + 0x04, true) + 8;

            return(IsValidPvrt(source, offset + pvrtOffset, length - pvrtOffset));
        }
Exemplo n.º 5
0
        /// <summary>
        /// Checks for and validates GBIX headers as well as PVRT.
        /// <para>See also: <seealso cref="IsValidPvrt"/></para>
        /// </summary>
        /// <param name="source">Byte array containing the data.</param>
        /// <param name="offset">The offset in the byte array to start at.</param>
        /// <param name="length">The expected length of the data minus the preceding header sizes.</param>
        /// <returns>True if the header is GBIX and it passes validation, false otherwise.</returns>
        private static bool IsValidGbix(byte[] source, int offset, uint length)
        {
            if (!PTMethods.Contains(source, offset + 0x00, gbixFourCC))
            {
                return(false);
            }

            // Immediately after the "GBIX" part of the GBIX header, there is
            // an offset indicating where the PVRT header begins relative to 0x08.
            var dataOffset = offset + BitConverter.ToInt32(source, offset + 0x04) + (gbixSizeInBytes - gbixFourCC.Length);

            return(IsValidPvrt(source, dataOffset, length - (uint)(dataOffset - offset)));
        }
Exemplo n.º 6
0
        /// <summary>
        /// Determines if this is a PVR texture.
        /// </summary>
        /// <param name="source">Byte array containing the data.</param>
        /// <param name="offset">The offset in the byte array to start at.</param>
        /// <param name="length">Length of the data (in bytes).</param>
        /// <returns>True if this is a PVR texture, false otherwise.</returns>
        public static bool Is(byte[] source, int offset, int length)
        {
            // GBIX and PVRT
            //if (length >= 0x20 &&
            //    PTMethods.Contains(source, offset + 0x00, Encoding.UTF8.GetBytes("GBIX")) &&
            //    PTMethods.Contains(source, offset + 0x10, Encoding.UTF8.GetBytes("PVRT")) &&
            //    source[offset + 0x19] < 0x60 &&
            //    BitConverter.ToUInt32(source, offset + 0x14) == length - 24)
            if (length >= 0x20 &&
                PTMethods.Contains(source, offset + 0x00, Encoding.UTF8.GetBytes("GBIX")) &&
                PTMethods.Contains(source, offset + 0x10, Encoding.UTF8.GetBytes("PVRT")))
            {
                return(true);
            }

            // PVRT (and no GBIX chunk)
            else if (length >= 0x10 &&
                     PTMethods.Contains(source, offset + 0x00, Encoding.UTF8.GetBytes("PVRT")) &&
                     source[offset + 0x09] < 0x60 &&
                     BitConverter.ToUInt32(source, offset + 0x04) == length - 8)
            {
                return(true);
            }

            // GBIX and PVRT with RLE compression
            else if (length >= 0x24 &&
                     PTMethods.Contains(source, offset + 0x04, Encoding.UTF8.GetBytes("GBIX")) &&
                     PTMethods.Contains(source, offset + 0x14, Encoding.UTF8.GetBytes("PVRT")) &&
                     source[offset + 0x1D] < 0x60 &&
                     BitConverter.ToUInt32(source, offset + 0x18) == BitConverter.ToUInt32(source, offset + 0x00) - 24)
            {
                return(true);
            }

            // PVRT (and no GBIX chunk) with RLE compression
            else if (length >= 0x14 &&
                     PTMethods.Contains(source, offset + 0x04, Encoding.UTF8.GetBytes("PVRT")) &&
                     source[offset + 0x0D] < 0x60 &&
                     BitConverter.ToUInt32(source, offset + 0x08) == BitConverter.ToUInt32(source, offset + 0x00) - 8)
            {
                return(true);
            }

            return(false);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Checks for the PVRT header and validates it.
        /// <para>See also: <seealso cref="IsValidGbix"/></para>
        /// </summary>
        /// <param name="source">Byte array containing the data.</param>
        /// <param name="offset">The offset in the byte array to start at.</param>
        /// <param name="length">The expected length of the PVR data minus the preceding header sizes.</param>
        /// <returns>True if the header is PVRT and it passes validation, false otherwise.</returns>
        private static bool IsValidPvrt(byte[] source, int offset, uint length)
        {
            if (!PTMethods.Contains(source, offset + 0x00, pvrtFourCC))
            {
                return(false);
            }

            if (source[offset + 0x09] >= 0x60)
            {
                return(false);
            }

            if (BitConverter.ToUInt32(source, offset + 0x04) != length - 8)
            {
                return(false);
            }

            return(true);
        }
Exemplo n.º 8
0
        /// <summary>
        /// Determines if this is a SVR texture.
        /// </summary>
        /// <param name="source">Byte array containing the data.</param>
        /// <param name="offset">The offset in the byte array to start at.</param>
        /// <param name="length">Length of the data (in bytes).</param>
        /// <returns>True if this is a SVR texture, false otherwise.</returns>
        public static bool Is(byte[] source, int offset, int length)
        {
            // GBIX and PVRT
            if (length >= 0x20 &&
                PTMethods.Contains(source, offset + 0x00, Encoding.UTF8.GetBytes("GBIX")) &&
                PTMethods.Contains(source, offset + 0x10, Encoding.UTF8.GetBytes("PVRT")) &&
                source[offset + 0x19] >= 0x60 && source[offset + 0x19] < 0x70 &&
                BitConverter.ToUInt32(source, offset + 0x14) == length - 24)
            {
                return(true);
            }

            // PVRT (and no GBIX chunk)
            else if (length >= 0x10 &&
                     PTMethods.Contains(source, offset + 0x00, Encoding.UTF8.GetBytes("PVRT")) &&
                     source[offset + 0x19] >= 0x60 && source[offset + 0x19] < 0x70 &&
                     BitConverter.ToUInt32(source, offset + 0x04) == length - 8)
            {
                return(true);
            }

            return(false);
        }
Exemplo n.º 9
0
        protected override void Initalize()
        {
            // Check to see if what we are dealing with is a PVR texture
            if (!Is(encodedData))
            {
                throw new NotAValidTextureException("This is not a valid PVR texture.");
            }

            // Determine the offsets of the GBIX (if present) and PVRT header chunks.
            if (PTMethods.Contains(encodedData, 0x00, Encoding.UTF8.GetBytes("GBIX")))
            {
                gbixOffset = 0x00;
                pvrtOffset = 0x10;
            }
            else if (PTMethods.Contains(encodedData, 0x04, Encoding.UTF8.GetBytes("GBIX")))
            {
                gbixOffset = 0x04;
                pvrtOffset = 0x14;
            }
            else if (PTMethods.Contains(encodedData, 0x04, Encoding.UTF8.GetBytes("PVRT")))
            {
                gbixOffset = -1;
                pvrtOffset = 0x04;
            }
            else
            {
                gbixOffset = -1;
                pvrtOffset = 0x00;
            }

            // Read the global index (if it is present). If it is not present, just set it to 0.
            if (gbixOffset != -1)
            {
                globalIndex = BitConverter.ToUInt32(encodedData, gbixOffset + 0x08);
            }
            else
            {
                globalIndex = 0;
            }

            // Read information about the texture
            textureWidth  = BitConverter.ToUInt16(encodedData, pvrtOffset + 0x0C);
            textureHeight = BitConverter.ToUInt16(encodedData, pvrtOffset + 0x0E);

            pixelFormat = (PvrPixelFormat)encodedData[pvrtOffset + 0x08];
            dataFormat  = (PvrDataFormat)encodedData[pvrtOffset + 0x09];

            // Get the codecs and make sure we can decode using them
            pixelCodec = PvrPixelCodec.GetPixelCodec(pixelFormat);
            dataCodec  = PvrDataCodec.GetDataCodec(dataFormat);

            if (dataCodec != null && pixelCodec != null)
            {
                dataCodec.PixelCodec = pixelCodec;
                canDecode            = true;
            }

            // Set the palette and data offsets
            if (!canDecode || dataCodec.PaletteEntries == 0 || dataCodec.NeedsExternalPalette)
            {
                paletteOffset = -1;
                dataOffset    = pvrtOffset + 0x10;
            }
            else
            {
                paletteOffset = pvrtOffset + 0x10;
                dataOffset    = paletteOffset + (dataCodec.PaletteEntries * (pixelCodec.Bpp >> 3));
            }

            // Get the compression format and determine if we need to decompress this texture
            compressionFormat = GetCompressionFormat(encodedData, pvrtOffset, dataOffset);
            compressionCodec  = PvrCompressionCodec.GetCompressionCodec(compressionFormat);

            if (compressionFormat != PvrCompressionFormat.None && compressionCodec != null)
            {
                encodedData = compressionCodec.Decompress(encodedData, dataOffset, pixelCodec, dataCodec);

                // Now place the offsets in the appropiate area
                if (compressionFormat == PvrCompressionFormat.Rle)
                {
                    if (gbixOffset != -1)
                    {
                        gbixOffset -= 4;
                    }
                    pvrtOffset -= 4;
                    if (paletteOffset != -1)
                    {
                        paletteOffset -= 4;
                    }
                    dataOffset -= 4;
                }
            }

            // If the texture contains mipmaps, gets the offsets of them
            if (canDecode && dataCodec.HasMipmaps)
            {
                mipmapOffsets = new int[(int)Math.Log(textureWidth, 2) + 1];

                int mipmapOffset = 0;

                // Calculate the padding for the first mipmap offset
                if (dataFormat == PvrDataFormat.SquareTwiddledMipmaps)
                {
                    // A 1x1 mipmap takes up as much space as a 2x1 mipmap
                    mipmapOffset = (dataCodec.Bpp) >> 3;
                }
                if (dataFormat == PvrDataFormat.SquareTwiddledMipmapsAlt)
                {
                    // A 1x1 mipmap takes up as much space as a 2x2 mipmap
                    mipmapOffset = (3 * dataCodec.Bpp) >> 3;
                }

                for (int i = mipmapOffsets.Length - 1, size = 1; i >= 0; i--, size <<= 1)
                {
                    mipmapOffsets[i] = mipmapOffset;

                    mipmapOffset += Math.Max((size * size * dataCodec.Bpp) >> 3, 1);
                }
            }

            initalized = true;
        }
Exemplo n.º 10
0
 /// <summary>
 /// Checks for the PVRT header and validates it.
 /// <para>See also: <seealso cref="IsValidGbix"/></para>
 /// </summary>
 /// <param name="source">Byte array containing the data.</param>
 /// <param name="offset">The offset in the byte array to start at.</param>
 /// <param name="length">The expected length of the PVR data minus the preceding header sizes.</param>
 /// <returns>True if the header is PVRT and it passes validation, false otherwise.</returns>
 private static bool IsValidPvrt(byte[] source, int offset, int length)
 {
     return(PTMethods.Contains(source, offset, pvrtFourCC) &&
            source[offset + 0x09] < 0x60 &&
            PTMethods.ToUInt32(source, offset + 0x04, true) == length - 8);
 }
Exemplo n.º 11
0
        protected override void Initalize()
        {
            // Check to see if what we are dealing with is a GVR texture
            if (!Is(encodedData))
            {
                throw new NotAValidTextureException("This is not a valid GVR texture.");
            }

            // Determine the offsets of the GBIX/GCIX (if present) and GCIX header chunks.
            if (PTMethods.Contains(encodedData, 0, Encoding.UTF8.GetBytes("GBIX")) ||
                PTMethods.Contains(encodedData, 0, Encoding.UTF8.GetBytes("GCIX")))
            {
                gbixOffset = 0x00;
                pvrtOffset = 0x10;
            }
            else
            {
                gbixOffset = -1;
                pvrtOffset = 0x00;
            }

            // Read the global index (if it is present). If it is not present, just set it to 0.
            if (gbixOffset != -1)
            {
                globalIndex = PTMethods.ToUInt32BE(encodedData, gbixOffset + 0x08);
            }
            else
            {
                globalIndex = 0;
            }

            // Read information about the texture
            textureWidth  = PTMethods.ToUInt16BE(encodedData, pvrtOffset + 0x0C);
            textureHeight = PTMethods.ToUInt16BE(encodedData, pvrtOffset + 0x0E);

            pixelFormat = (GvrPixelFormat)(encodedData[pvrtOffset + 0x0A] >> 4); // Only the first 4 bits matter
            dataFlags   = (GvrDataFlags)(encodedData[pvrtOffset + 0x0A] & 0x0F); // Only the last 4 bits matter
            dataFormat  = (GvrDataFormat)encodedData[pvrtOffset + 0x0B];

            // Get the codecs and make sure we can decode using them
            dataCodec = GvrDataCodec.GetDataCodec(dataFormat);

            // We need a pixel codec if this is a palettized texture
            if (dataCodec != null && dataCodec.PaletteEntries != 0)
            {
                pixelCodec = GvrPixelCodec.GetPixelCodec(pixelFormat);

                if (pixelCodec != null)
                {
                    dataCodec.PixelCodec = pixelCodec;
                    canDecode            = true;
                }
            }
            else
            {
                pixelFormat = GvrPixelFormat.Unknown;

                if (dataCodec != null)
                {
                    canDecode = true;
                }
            }

            // Set the palette and data offsets
            paletteEntries = dataCodec.PaletteEntries;
            if (!canDecode || paletteEntries == 0 || (paletteEntries != 0 && (dataFlags & GvrDataFlags.ExternalPalette) != 0))
            {
                paletteOffset = -1;
                dataOffset    = pvrtOffset + 0x10;
            }
            else
            {
                paletteOffset = pvrtOffset + 0x10;
                dataOffset    = paletteOffset + (paletteEntries * (pixelCodec.Bpp >> 3));
            }

            // If the texture contains mipmaps, gets the offsets of them
            if (canDecode && paletteEntries == 0 && (dataFlags & GvrDataFlags.Mipmaps) != 0)
            {
                mipmapOffsets = new int[(int)Math.Log(textureWidth, 2) + 1];

                int mipmapOffset = 0;
                for (int i = 0, size = textureWidth; i < mipmapOffsets.Length; i++, size >>= 1)
                {
                    mipmapOffsets[i] = mipmapOffset;
                    mipmapOffset    += Math.Max(size * size * (dataCodec.Bpp >> 3), 32);
                }
            }

            initalized = true;
        }
Exemplo n.º 12
0
        protected override void Initalize()
        {
            // Check to see if what we are dealing with is a SVR texture
            if (!Is(encodedData))
            {
                throw new NotAValidTextureException("This is not a valid GVR texture.");
            }

            // Determine the offsets of the GBIX (if present) and PVRT header chunks.
            if (PTMethods.Contains(encodedData, 0, Encoding.UTF8.GetBytes("GBIX")))
            {
                gbixOffset = 0x00;
                pvrtOffset = 0x10;
            }
            else
            {
                gbixOffset = -1;
                pvrtOffset = 0x00;
            }

            // Read the global index (if it is present). If it is not present, just set it to 0.
            if (gbixOffset != -1)
            {
                globalIndex = BitConverter.ToUInt32(encodedData, gbixOffset + 0x08);
            }
            else
            {
                globalIndex = 0;
            }

            // Read information about the texture
            textureWidth  = BitConverter.ToUInt16(encodedData, pvrtOffset + 0x0C);
            textureHeight = BitConverter.ToUInt16(encodedData, pvrtOffset + 0x0E);

            pixelFormat = (SvrPixelFormat)encodedData[pvrtOffset + 0x08];
            dataFormat  = (SvrDataFormat)encodedData[pvrtOffset + 0x09];

            // Get the codecs and make sure we can decode using them
            pixelCodec = SvrPixelCodec.GetPixelCodec(pixelFormat);
            dataCodec  = SvrDataCodec.GetDataCodec(dataFormat);

            if (dataCodec != null && pixelCodec != null)
            {
                dataCodec.PixelCodec = pixelCodec;
                canDecode            = true;
            }

            // Set the palette and data offsets
            paletteEntries = dataCodec.PaletteEntries;
            if (!canDecode || paletteEntries == 0 || dataCodec.NeedsExternalPalette)
            {
                paletteOffset = -1;
                dataOffset    = pvrtOffset + 0x10;
            }
            else
            {
                paletteOffset = pvrtOffset + 0x10;
                dataOffset    = paletteOffset + (paletteEntries * (pixelCodec.Bpp >> 3));
            }

            initalized = true;
        }
Exemplo n.º 13
0
 /// <summary>
 /// Checks for the XVRT header and validates it.
 /// </summary>
 /// <param name="source">Byte array containing the data.</param>
 /// <param name="offset">The offset in the byte array to start at.</param>
 /// <param name="length">The expected length of the PVR data minus the preceding header sizes.</param>
 /// <returns>True if the header is XVRT and it passes validation, false otherwise.</returns>
 private static bool IsValidXvrt(byte[] source, int offset, int length)
 {
     return(PTMethods.Contains(source, offset, xvrtFourCC) &&
            BitConverter.ToUInt32(source, offset + 0x04) == length - 8);
 }