Example #1
0
        private static string DataFormatToString(PvrDataFormat format)
        {
            switch (format)
            {
            case PvrDataFormat.SquareTwiddled:           return("Square Twiddled");

            case PvrDataFormat.SquareTwiddledMipmaps:    return("Square Twiddled with Mipmaps");

            case PvrDataFormat.Vq:                       return("VQ");

            case PvrDataFormat.VqMipmaps:                return("VQ with Mipmaps");

            case PvrDataFormat.Index4:                   return("4-bit Indexed with External Palette");

            case PvrDataFormat.Index8:                   return("8-bit Indexed with External Palette");

            case PvrDataFormat.Rectangle:                return("Rectangle");

            case PvrDataFormat.RectangleTwiddled:        return("Rectangle Twiddled");

            case PvrDataFormat.SmallVq:                  return("Small VQ");

            case PvrDataFormat.SmallVqMipmaps:           return("Small VQ with Mipmaps");

            case PvrDataFormat.SquareTwiddledMipmapsAlt: return("Square Twiddled with Mipmaps (Alternate)");
            }

            return("Unknown");
        }
 /// <summary>
 /// Opens a texture to encode from a file.
 /// </summary>
 /// <param name="file">Filename of the file that contains the texture data.</param>
 /// <param name="pixelFormat">Pixel format to encode the texture to.</param>
 /// <param name="dataFormat">Data format to encode the texture to.</param>
 public PvrTextureEncoder(string file, PvrPixelFormat pixelFormat, PvrDataFormat dataFormat) : base(file)
 {
     if (decodedBitmap != null)
     {
         initalized = Initalize(pixelFormat, dataFormat);
     }
 }
Example #3
0
        public static PvrDataCodec GetDataCodec(PvrDataFormat format)
        {
            switch (format)
            {
                case PvrDataFormat.SquareTwiddled:
                    return new SquareTwiddled();
                case PvrDataFormat.SquareTwiddledMipmaps:
                case PvrDataFormat.SquareTwiddledMipmapsAlt:
                    return new SquareTwiddledMipmaps();
                case PvrDataFormat.Vq:
                    return new Vq();
                case PvrDataFormat.VqMipmaps:
                    return new VqMipmaps();
                case PvrDataFormat.Index4:
                    return new Index4();
                case PvrDataFormat.Index8:
                    return new Index8();
                case PvrDataFormat.Rectangle:
                    return new Rectangle();
                case PvrDataFormat.RectangleTwiddled:
                    return new RectangleTwiddled();
                case PvrDataFormat.SmallVq:
                    return new SmallVq();
                case PvrDataFormat.SmallVqMipmaps:
                    return new SmallVqMipmaps();
            }

            return null;
        }
Example #4
0
        /// <summary>
        /// Open a bitmap from a byte array.
        /// </summary>
        /// <param name="array">Byte array that contains the bitmap data.</param>
        /// <param name="PixelFormat">Pixel Format</param>
        /// <param name="DataFormat">Data Format</param>
        public PvrTextureEncoder(byte[] array, PvrPixelFormat PixelFormat, PvrDataFormat DataFormat)
            : base(array)
        {
            this.PixelFormat = (byte)PixelFormat;
            this.DataFormat  = (byte)DataFormat;

            InitSuccess = Initalize();
        }
Example #5
0
        /// <summary>
        /// Open a bitmap from a stream.
        /// </summary>
        /// <param name="stream">Stream that contains the bitmap data.</param>
        /// <param name="PixelFormat">Pixel Format</param>
        /// <param name="DataFormat">Data Format</param>
        public PvrTextureEncoder(Stream stream, PvrPixelFormat PixelFormat, PvrDataFormat DataFormat)
            : base(stream)
        {
            this.PixelFormat = (byte)PixelFormat;
            this.DataFormat  = (byte)DataFormat;

            InitSuccess = Initalize();
        }
Example #6
0
        PvrCompressionFormat CompressionFormat; // Compression Format

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Open a bitmap from a file.
        /// </summary>
        /// <param name="file">Filename of the file that contains the bitmap data.</param>
        /// <param name="PixelFormat">Pixel Format</param>
        /// <param name="DataFormat">Data Format</param>
        public PvrTextureEncoder(string file, PvrPixelFormat PixelFormat, PvrDataFormat DataFormat)
            : base(file)
        {
            this.PixelFormat = (byte)PixelFormat;
            this.DataFormat  = (byte)DataFormat;

            InitSuccess = Initalize();
        }
Example #7
0
        /// <summary>
        /// Open a bitmap from a System.Drawing.Bitmap.
        /// </summary>
        /// <param name="bitmap">A System.Drawing.Bitmap instance.</param>
        /// <param name="PixelFormat">Pixel Format</param>
        /// <param name="DataFormat">Data Format</param>
        public PvrTextureEncoder(Bitmap bitmap, PvrPixelFormat PixelFormat, PvrDataFormat DataFormat)
            : base(bitmap)
        {
            this.PixelFormat = (byte)PixelFormat;
            this.DataFormat  = (byte)DataFormat;

            InitSuccess = Initalize();
        }
 /// <summary>
 /// Opens a texture to encode from a file.
 /// </summary>
 /// <param name="file">Filename of the file that contains the texture data.</param>
 /// <param name="pixelFormat">Pixel format to encode the texture to.</param>
 /// <param name="dataFormat">Data format to encode the texture to.</param>
 public PvrTextureEncoder(string file, PvrPixelFormat pixelFormat, PvrDataFormat dataFormat)
     : base(file)
 {
     if (decodedBitmap != null)
     {
         initalized = Initalize(pixelFormat, dataFormat);
     }
 }
 /// <summary>
 /// Opens a texture to encode from a byte array.
 /// </summary>
 /// <param name="source">Byte array that contains the texture data.</param>
 /// <param name="pixelFormat">Pixel format to encode the texture to.</param>
 /// <param name="dataFormat">Data format to encode the texture to.</param>
 public PvrTextureEncoder(byte[] source, PvrPixelFormat pixelFormat, PvrDataFormat dataFormat)
     : base(source)
 {
     if (decodedBitmap != null)
     {
         initalized = Initalize(pixelFormat, dataFormat);
     }
 }
 /// <summary>
 /// Opens a texture to encode from a bitmap.
 /// </summary>
 /// <param name="source">Bitmap to encode.</param>
 /// <param name="pixelFormat">Pixel format to encode the texture to.</param>
 /// <param name="dataFormat">Data format to encode the texture to.</param>
 public PvrTextureEncoder(Bitmap source, PvrPixelFormat pixelFormat, PvrDataFormat dataFormat, uint globalIndex, PvrCompressionFormat compression)
     : base(source)
 {
     if (decodedBitmap != null)
     {
         initalized = Initalize(pixelFormat, dataFormat, globalIndex, compressionFormat);
     }
 }
Example #11
0
 /// <summary>
 /// Opens a texture to encode from a stream.
 /// </summary>
 /// <param name="source">Stream that contains the texture data.</param>
 /// <param name="pixelFormat">Pixel format to encode the texture to.</param>
 /// <param name="dataFormat">Data format to encode the texture to.</param>
 public PvrTextureEncoder(Stream source, PvrPixelFormat pixelFormat, PvrDataFormat dataFormat)
     : base(source)
 {
     if (decodedBitmap != null)
     {
         initalized = Initalize(pixelFormat, dataFormat);
     }
 }
Example #12
0
 /// <summary>
 /// Opens a texture to encode from a byte array.
 /// </summary>
 /// <param name="source">Byte array that contains the texture data.</param>
 /// <param name="offset">Offset of the texture in the array.</param>
 /// <param name="length">Number of bytes to read.</param>
 /// <param name="pixelFormat">Pixel format to encode the texture to.</param>
 /// <param name="dataFormat">Data format to encode the texture to.</param>
 public PvrTextureEncoder(byte[] source, int offset, int length, PvrPixelFormat pixelFormat, PvrDataFormat dataFormat)
     : base(source, offset, length)
 {
     if (decodedBitmap != null)
     {
         initalized = Initalize(pixelFormat, dataFormat);
     }
 }
Example #13
0
 public PBTextureHeader(int offset, PvrPixelFormat pxformat, PvrDataFormat dataformat, uint gbix, ushort width, ushort height)
 {
     Offset      = offset;
     PixelFormat = pxformat;
     DataFormat  = dataformat;
     GBIX        = gbix;
     Width       = width;
     Height      = height;
 }
Example #14
0
        /// <summary>
        /// Opens a texture to encode from a file.
        /// </summary>
        /// <param name="file">Filename of the file that contains the texture data.</param>
        /// <param name="pixelFormat">Pixel format to encode the texture to.</param>
        /// <param name="dataFormat">Data format to encode the texture to.</param>
        public PvrTextureEncoder(string file, PvrPixelFormat pixelFormat, PvrDataFormat dataFormat)
        {
            Initalize(new Bitmap(file));

            if (m_decodedBitmap != null)
            {
                Initalize(pixelFormat, dataFormat);
            }
        }
Example #15
0
        /// <summary>
        /// Opens a texture to encode from a bitmap.
        /// </summary>
        /// <param name="source">Bitmap to encode.</param>
        /// <param name="pixelFormat">Pixel format to encode the texture to.</param>
        /// <param name="dataFormat">Data format to encode the texture to.</param>
        public PvrTextureEncoder(Bitmap source, PvrPixelFormat pixelFormat, PvrDataFormat dataFormat)
        {
            Initalize(source);

            if (m_decodedBitmap != null)
            {
                Initalize(pixelFormat, dataFormat);
            }
        }
Example #16
0
        /// <summary>
        /// Opens a texture to encode from a byte array.
        /// </summary>
        /// <param name="source">Byte array that contains the texture data.</param>
        /// <param name="pixelFormat">Pixel format to encode the texture to.</param>
        /// <param name="dataFormat">Data format to encode the texture to.</param>
        public PvrTextureEncoder(byte[] source, PvrPixelFormat pixelFormat, PvrDataFormat dataFormat)
        {
            MemoryStream buffer = new MemoryStream();

            buffer.Write(source, 0, source.Length);
            Initalize(new Bitmap(buffer));

            if (m_decodedBitmap != null)
            {
                Initalize(pixelFormat, dataFormat);
            }
        }
Example #17
0
        /// <summary>
        /// Opens a texture to encode from a stream.
        /// </summary>
        /// <param name="source">Stream that contains the texture data.</param>
        /// <param name="pixelFormat">Pixel format to encode the texture to.</param>
        /// <param name="dataFormat">Data format to encode the texture to.</param>
        public PvrTextureEncoder(Stream source, PvrPixelFormat pixelFormat, PvrDataFormat dataFormat)
        {
            MemoryStream buffer = new MemoryStream();

            PTStream.CopyPartTo(source, buffer, (int)(source.Length - source.Position));
            Initalize(new Bitmap(buffer));

            if (m_decodedBitmap != null)
            {
                Initalize(pixelFormat, dataFormat);
            }
        }
Example #18
0
        private bool Initalize(PvrPixelFormat pixelFormat, PvrDataFormat dataFormat)
        {
            // Set the default values
            HasGlobalIndex    = true;
            GlobalIndex       = 0;
            CompressionFormat = PvrCompressionFormat.NONE;

            // Set the data format and pixel format and load the appropiate codecs
            this.PixelFormat = pixelFormat;
            PixelCodec       = PvrPixelCodec.GetPixelCodec(pixelFormat);

            this.DataFormat = dataFormat;
            DataCodec       = PvrDataCodec.GetDataCodec(dataFormat);

            // Make sure the pixel and data codecs exists and we can encode to it
            if (PixelCodec == null || !PixelCodec.CanEncode)
            {
                return(false);
            }
            if (DataCodec == null || !DataCodec.CanEncode)
            {
                return(false);
            }
            DataCodec.PixelCodec = PixelCodec;

            if (DataCodec.PaletteEntries != 0)
            {
                if (DataCodec.VQ)
                {
                    m_decodedData = BitmapToRawVQ(m_decodedBitmap, DataCodec.PaletteEntries, out m_texturePalette);
                }
                else
                {
                    // Convert the bitmap to an array containing indicies.
                    m_decodedData = BitmapToRawIndexed(m_decodedBitmap, DataCodec.PaletteEntries, out m_texturePalette);

                    // If this texture has an external palette file, set up the palette encoder
                    if (DataCodec.NeedsExternalPalette)
                    {
                        PaletteEncoder = new PvpPaletteEncoder(m_texturePalette, (ushort)DataCodec.PaletteEntries, pixelFormat, PixelCodec);
                    }
                }
            }
            else
            {
                // Convert the bitmap to an array
                m_decodedData = BitmapToRaw(m_decodedBitmap);
            }

            return(true);
        }
Example #19
0
        public static PvrDataCodec GetDataCodec(PvrDataFormat format)
        {
            switch (format)
            {
            case PvrDataFormat.SQUARE_TWIDDLED:
                return(new SquareTwiddled());

            case PvrDataFormat.SQUARE_TWIDDLED_MIPMAP:
            case PvrDataFormat.SQUARE_TWIDDLED_MIPMAP_ALT:
                return(new SquareTwiddledMipmaps());

            case PvrDataFormat.VECTOR_QUANTIZATION:
                return(new Vq());

            case PvrDataFormat.VECTOR_QUANTIZATION_MIPMAP:
                return(new VqMipmaps());

            case PvrDataFormat.PALETTIZE_4BIT:
                return(new Index4());

            case PvrDataFormat.PALETTIZE_4BIT_MIPMAP:
                return(new Index4Mipmap());

            case PvrDataFormat.PALETTIZE_8BIT:
                return(new Index8());

            case PvrDataFormat.PALETTIZE_8BIT_MIPMAP:
                return(new Index8Mipmap());

            case PvrDataFormat.RAW:
            case PvrDataFormat.RECTANGLE:
            case PvrDataFormat.RECTANGLE_STRIDE:
                return(new Rectangle());

            case PvrDataFormat.RECTANGLE_TWIDDLED:
                return(new RectangleTwiddled());

            case PvrDataFormat.VECTOR_QUANTIZATION_SMALL:
                return(new SmallVq());

            case PvrDataFormat.VECTOR_QUANTIZATION_SMALL_MIPMAP:
                return(new SmallVqMipmaps());
            }

            return(null);
        }
Example #20
0
        private bool Initalize(PvrPixelFormat pixelFormat, PvrDataFormat dataFormat)
        {
            // Set the default values
            hasGlobalIndex    = true;
            globalIndex       = 0;
            compressionFormat = PvrCompressionFormat.None;

            // Set the data format and pixel format and load the appropiate codecs
            this.pixelFormat = pixelFormat;
            pixelCodec       = PvrPixelCodec.GetPixelCodec(pixelFormat);

            this.dataFormat = dataFormat;
            dataCodec       = PvrDataCodec.GetDataCodec(dataFormat);

            // Make sure the pixel and data codecs exists and we can encode to it
            if (pixelCodec == null || !pixelCodec.CanEncode)
            {
                return(false);
            }
            if (dataCodec == null || !dataCodec.CanEncode)
            {
                return(false);
            }
            dataCodec.PixelCodec = pixelCodec;

            if (dataCodec.PaletteEntries != 0)
            {
                // Convert the bitmap to an array containing indicies.
                decodedData = BitmapToRawIndexed(decodedBitmap, dataCodec.PaletteEntries, out texturePalette);

                // If this texture has an external palette file, set up the palette encoder
                if (dataCodec.NeedsExternalPalette)
                {
                    paletteEncoder = new PvpPaletteEncoder(texturePalette, (ushort)dataCodec.PaletteEntries, pixelFormat, pixelCodec);
                }
            }
            else
            {
                // Convert the bitmap to an array
                decodedData = BitmapToRaw(decodedBitmap);
            }

            return(true);
        }
Example #21
0
        public static PvrDataCodec GetDataCodec(PvrDataFormat format)
        {
            switch (format)
            {
            case PvrDataFormat.SquareTwiddled:
                return(new SquareTwiddled());

            case PvrDataFormat.SquareTwiddledMipmaps:
            case PvrDataFormat.SquareTwiddledMipmapsAlt:
                return(new SquareTwiddledMipmaps());

            case PvrDataFormat.Vq:
                return(new Vq());

            case PvrDataFormat.VqMipmaps:
                return(new VqMipmaps());

            case PvrDataFormat.Index4:
                return(new Index4());

            case PvrDataFormat.Index8:
                return(new Index8());

            case PvrDataFormat.Rectangle:
                return(new Rectangle());

            case PvrDataFormat.RectangleTwiddled:
                return(new RectangleTwiddled());

            case PvrDataFormat.SmallVq:
                return(new SmallVq());

            case PvrDataFormat.SmallVqMipmaps:
                return(new SmallVqMipmaps());
            }

            return(null);
        }
Example #22
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, gbixFourCC))
            {
                gbixOffset = 0x00;
                pvrtOffset = 0x08 + BitConverter.ToInt32(encodedData, gbixOffset + 4);
            }
            else if (PTMethods.Contains(encodedData, 0x04, gbixFourCC))
            {
                gbixOffset = 0x04;
                pvrtOffset = 0x0C + BitConverter.ToInt32(encodedData, gbixOffset + 4);
            }
            else if (PTMethods.Contains(encodedData, 0x04, pvrtFourCC))
            {
                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 number of palette entries
            // The number in a Small Vq encoded texture various based on its size
            paletteEntries = dataCodec.PaletteEntries;
            if (dataFormat == PvrDataFormat.SmallVq || dataFormat == PvrDataFormat.SmallVqMipmaps)
            {
                if (textureWidth <= 16)
                {
                    paletteEntries = 64; // Actually 16
                }
                else if (textureWidth <= 32)
                {
                    paletteEntries = 256; // Actually 64
                }
                else if (textureWidth <= 64)
                {
                    paletteEntries = 512; // Actually 128
                }
                else
                {
                    paletteEntries = 1024; // Actually 256
                }
            }

            // Set the palette and data offsets
            if (!canDecode || paletteEntries == 0 || dataCodec.NeedsExternalPalette)
            {
                paletteOffset = -1;
                dataOffset = pvrtOffset + 0x10;
            }
            else
            {
                paletteOffset = pvrtOffset + 0x10;
                dataOffset = paletteOffset + (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;
                }
                else 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;
        }
 private bool Initalize(PvrPixelFormat pixelFormat, PvrDataFormat dataFormat)
 {
     return(Initalize(pixelFormat, dataFormat, 0, PvrCompressionFormat.None));
 }
Example #24
0
        static void Main(string[] args)
        {
            string            directoryName;
            string            FullLine;
            string            texturename;
            UInt32            GBIX             = 0;
            List <String>     textureNames     = new List <String>();
            List <PvrTexture> finalTextureList = new List <PvrTexture>();

            if (args.Length == 0)
            {
                Console.WriteLine("Error - no texturelist provided. Provide a path to a texturelist as your first command line argument");
                Console.WriteLine("Press ENTER to continue...");
                Console.ReadLine();
                return;
            }
            String filePath = args[0];

            directoryName = Path.GetDirectoryName(filePath);
            string archiveName = Path.GetFileNameWithoutExtension(filePath);

            if (File.Exists(filePath))
            {
                StreamReader texlistStream = File.OpenText(filePath);
                while (!texlistStream.EndOfStream)
                {
                    textureNames.Add(texlistStream.ReadLine());
                }
                PvmArchive       pvmArchive = new PvmArchive();
                Stream           pvmStream  = File.Open(Path.ChangeExtension(filePath, ".pvm"), FileMode.Create);
                PvmArchiveWriter pvmWriter  = (PvmArchiveWriter)pvmArchive.Create(pvmStream);
                // Reading in textures
                for (uint imgIndx = 0; imgIndx < textureNames.Count; imgIndx++)
                {
                    FullLine = textureNames[(int)imgIndx];
                    if (string.IsNullOrEmpty(FullLine))
                    {
                        continue;
                    }
                    String[] substrings = FullLine.Split(',');
                    GBIX        = UInt32.Parse(substrings[0]);
                    texturename = substrings[1];
                    Bitmap tempTexture = new Bitmap(8, 8);
                    string texturePath = Path.Combine(directoryName, Path.ChangeExtension(texturename, ".png"));
                    if (File.Exists(texturePath))
                    {
                        Console.WriteLine("Adding texture:" + (texturePath));
                        tempTexture = (Bitmap)Bitmap.FromFile(texturePath);
                        tempTexture = tempTexture.Clone(new Rectangle(Point.Empty, tempTexture.Size), System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                    }
                    else
                    {
                        Console.WriteLine(String.Concat("Texture ", textureNames[(int)imgIndx], " not found. Generating a placeholder. Check your files."));
                    }

                    System.Drawing.Imaging.BitmapData bmpd = tempTexture.LockBits(new Rectangle(Point.Empty, tempTexture.Size), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                    int    stride = bmpd.Stride;
                    byte[] bits   = new byte[Math.Abs(stride) * bmpd.Height];
                    System.Runtime.InteropServices.Marshal.Copy(bmpd.Scan0, bits, 0, bits.Length);
                    tempTexture.UnlockBits(bmpd);
                    int tlevels = 0;
                    for (int y = 0; y < tempTexture.Height; y++)
                    {
                        int srcaddr = y * Math.Abs(stride);
                        for (int x = 0; x < tempTexture.Width; x++)
                        {
                            Color c = Color.FromArgb(BitConverter.ToInt32(bits, srcaddr + (x * 4)));
                            if (c.A == 0)
                            {
                                tlevels = 1;
                            }
                            else if (c.A < 255)
                            {
                                tlevels = 2;
                                break;
                            }
                        }
                        if (tlevels == 2)
                        {
                            break;
                        }
                    }
                    PvrPixelFormat ppf = PvrPixelFormat.Rgb565;
                    if (tlevels == 1)
                    {
                        ppf = PvrPixelFormat.Argb1555;
                    }
                    else if (tlevels == 2)
                    {
                        ppf = PvrPixelFormat.Argb4444;
                    }
                    PvrDataFormat pdf = PvrDataFormat.Rectangle;
                    if (tempTexture.Width == tempTexture.Height)
                    {
                        pdf = PvrDataFormat.SquareTwiddled;
                    }
                    PvrTextureEncoder encoder = new PvrTextureEncoder(tempTexture, ppf, pdf);
                    encoder.GlobalIndex = GBIX;
                    string pvrPath = Path.ChangeExtension(texturePath, ".pvr");
                    encoder.Save(pvrPath);

                    pvmWriter.CreateEntryFromFile(pvrPath);
                }

                pvmWriter.Flush();
                pvmStream.Close();
                Console.WriteLine("PVM was compiled successfully!");
                Console.WriteLine("Press ENTER to continue...");
                Console.ReadLine();
                return;
            }
            else             // error, supplied path is invalid
            {
                Console.WriteLine("Supplied texturelist does not exist!");
                Console.WriteLine("Press ENTER to continue...");
                Console.ReadLine();
                return;
            }
        }
Example #25
0
        // Checks to see if we can encode the texture based on data format specific things
        private bool CanEncode(PvrPixelFormat PixelFormat, PvrDataFormat DataFormat, int width, int height)
        {
            // The converter should check to see that a pixel codec and data codec exists,
            // along with checking that width >= 8 and height >= 8, and width and height are powers of 2.
            switch (DataFormat)
            {
                case PvrDataFormat.SquareTwiddled:
                case PvrDataFormat.SquareTwiddledMipmaps:
                case PvrDataFormat.Vq:
                case PvrDataFormat.VqMipmaps:
                case PvrDataFormat.SquareTwiddledMipmapsDup:
                    return (width == height);
                case PvrDataFormat.SmallVq:
                    return (width == height && width <= 64);
                case PvrDataFormat.SmallVqMipmaps:
                    return (width == height && width <= 32);
            }

            return true;
        }
Example #26
0
        private bool Initalize(PvrPixelFormat pixelFormat, PvrDataFormat dataFormat)
        {
            // Set the default values
            hasGlobalIndex = true;
            globalIndex = 0;
            compressionFormat = PvrCompressionFormat.None;

            // Set the data format and pixel format and load the appropiate codecs
            this.pixelFormat = pixelFormat;
            pixelCodec = PvrPixelCodec.GetPixelCodec(pixelFormat);

            this.dataFormat = dataFormat;
            dataCodec = PvrDataCodec.GetDataCodec(dataFormat);

            // Make sure the pixel and data codecs exists and we can encode to it
            if (pixelCodec == null || !pixelCodec.CanEncode) return false;
            if (dataCodec == null || !dataCodec.CanEncode) return false;
            dataCodec.PixelCodec = pixelCodec;

            if (dataCodec.PaletteEntries != 0)
            {
                // Convert the bitmap to an array containing indicies.
                decodedData = BitmapToRawIndexed(decodedBitmap, dataCodec.PaletteEntries, out texturePalette);

                // If this texture has an external palette file, set up the palette encoder
                if (dataCodec.NeedsExternalPalette)
                {
                    paletteEncoder = new PvpPaletteEncoder(texturePalette, (ushort)dataCodec.PaletteEntries, pixelFormat, pixelCodec);
                }
            }
            else
            {
                // Convert the bitmap to an array
                decodedData = BitmapToRaw(decodedBitmap);
            }

            return true;
        }
Example #27
0
        /// <summary>
        /// Convert a GBIX indexed texture pack to PVM.
        /// </summary>
        static void TexPack2PVM(string[] args)
        {
            bool compressPRS = false;

            if (args[args.Length - 1] == "-prs")
            {
                compressPRS = true;
            }
            filePath = args[1];
            string            FullLine;
            string            texturename;
            uint              GBIX             = 0;
            List <string>     textureNames     = new List <String>();
            List <PvrTexture> finalTextureList = new List <PvrTexture>();

            directoryName = Path.GetDirectoryName(filePath);
            string archiveName = Path.GetFileNameWithoutExtension(filePath);

            if (Directory.Exists(filePath))
            {
                Console.WriteLine("Converting texture pack to PVM: {0}", Path.GetFullPath(filePath));
                StreamReader texlistStream = File.OpenText(Path.Combine(filePath, "index.txt"));
                while (!texlistStream.EndOfStream)
                {
                    textureNames.Add(texlistStream.ReadLine());
                }
                PuyoFile puyo = new PuyoFile();
                outputPath = Path.ChangeExtension(filePath, ".pvm");
                // Reading in textures
                for (uint imgIndx = 0; imgIndx < textureNames.Count; imgIndx++)
                {
                    FullLine = textureNames[(int)imgIndx];
                    if (string.IsNullOrEmpty(FullLine))
                    {
                        continue;
                    }
                    string[] substrings = FullLine.Split(',');
                    GBIX        = UInt32.Parse(substrings[0]);
                    texturename = substrings[1];
                    Bitmap tempTexture = new Bitmap(8, 8);
                    string texturePath = Path.Combine(filePath, Path.ChangeExtension(texturename, ".png"));
                    if (File.Exists(texturePath))
                    {
                        Console.WriteLine("Adding texture: " + (texturePath));
                        tempTexture = (Bitmap)Bitmap.FromFile(texturePath);
                        tempTexture = tempTexture.Clone(new Rectangle(Point.Empty, tempTexture.Size), System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                    }
                    else
                    {
                        Console.WriteLine(string.Concat("Texture ", textureNames[(int)imgIndx], " not found. Generating a placeholder. Check your files."));
                    }

                    System.Drawing.Imaging.BitmapData bmpd = tempTexture.LockBits(new Rectangle(Point.Empty, tempTexture.Size), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                    int    stride = bmpd.Stride;
                    byte[] bits   = new byte[Math.Abs(stride) * bmpd.Height];
                    System.Runtime.InteropServices.Marshal.Copy(bmpd.Scan0, bits, 0, bits.Length);
                    tempTexture.UnlockBits(bmpd);
                    int tlevels = 0;
                    for (int y = 0; y < tempTexture.Height; y++)
                    {
                        int srcaddr = y * Math.Abs(stride);
                        for (int x = 0; x < tempTexture.Width; x++)
                        {
                            Color c = Color.FromArgb(BitConverter.ToInt32(bits, srcaddr + (x * 4)));
                            if (c.A == 0)
                            {
                                tlevels = 1;
                            }
                            else if (c.A < 255)
                            {
                                tlevels = 2;
                                break;
                            }
                        }
                        if (tlevels == 2)
                        {
                            break;
                        }
                    }
                    PvrPixelFormat ppf = PvrPixelFormat.Rgb565;
                    if (tlevels == 1)
                    {
                        ppf = PvrPixelFormat.Argb1555;
                    }
                    else if (tlevels == 2)
                    {
                        ppf = PvrPixelFormat.Argb4444;
                    }
                    PvrDataFormat pdf = PvrDataFormat.Rectangle;
                    if (tempTexture.Width == tempTexture.Height)
                    {
                        pdf = PvrDataFormat.SquareTwiddled;
                    }
                    PvrTextureEncoder encoder = new PvrTextureEncoder(tempTexture, ppf, pdf);
                    encoder.GlobalIndex = GBIX;
                    string pvrPath = Path.ChangeExtension(texturePath, ".pvr");
                    encoder.Save(pvrPath);
                    puyo.Entries.Add(new PVMEntry(pvrPath));
                }
                File.WriteAllBytes(outputPath, puyo.GetBytes());
                if (compressPRS)
                {
                    Console.WriteLine("Compressing to PRS...");
                    byte[] pvmdata = File.ReadAllBytes(Path.ChangeExtension(filePath, ".pvm"));
                    pvmdata    = FraGag.Compression.Prs.Compress(pvmdata);
                    outputPath = Path.ChangeExtension(filePath, ".prs");
                    File.WriteAllBytes(outputPath, pvmdata);
                    File.Delete(Path.ChangeExtension(filePath, ".pvm"));
                }
                Console.WriteLine("Output file: {0}", Path.GetFullPath(outputPath));
                Console.WriteLine("Archive was compiled successfully!");
            }
            else
            {
                Console.WriteLine("Supplied texture list does not exist!");
                Console.WriteLine("Press ENTER to continue...");
                Console.ReadLine();
                return;
            }
        }
Example #28
0
        /// <summary>
        /// 查找当前类型的图片
        /// </summary>
        /// <param name="byData">当前打开文件的字节数据</param>
        /// <param name="file">当前文件</param>
        /// <param name="imgInfos">查找到的图片的信息</param>
        /// <returns>是否查找成功</returns>
        public override List <byte[]> SearchImg(byte[] byData, string file, List <string> imgInfos)
        {
            List <byte[]> imgList = new List <byte[]>();

            // 分析文件内部是否包括Pvr文件
            for (int i = 0; i < byData.Length - 1024; i++)
            {
                if (byData[i] == 0x50 && byData[i + 1] == 0x56 && byData[i + 2] == 0x52 && byData[i + 3] == 0x54 &&
                    byData[i - 0x10] == 0x47 && byData[i - 0xf] == 0x42 && byData[i - 0xe] == 0x49 && byData[i - 0xd] == 0x58)
                {
                    PvrPixelFormat pixelFormat = (PvrPixelFormat)byData[i + 0x08];
                    PvrDataFormat  dataFormat  = (PvrDataFormat)byData[i + 0x09];

                    PvrPixelCodec pixelCodec = PvrPixelCodec.GetPixelCodec(pixelFormat);
                    PvrDataCodec  dataCodec  = PvrDataCodec.GetDataCodec(dataFormat);
                    if (dataCodec == null)
                    {
                        continue;
                    }
                    dataCodec.PixelCodec = pixelCodec;
                    int byCountPalette = 0;
                    if (pixelCodec == null && byData[i + 0x08] == 0x6)
                    {
                        byCountPalette = 4;
                    }
                    else
                    {
                        byCountPalette = pixelCodec.Bpp >> 3;
                    }

                    // 取得图片大小
                    int width  = (byData[i + 0xD] << 8) | byData[i + 0xC];
                    int height = (byData[i + 0xF] << 8) | byData[i + 0xE];

                    int imgByCount = (width * height * dataCodec.Bpp / 8) + (dataCodec.PaletteEntries * byCountPalette);
                    if (imgByCount == 0 || imgByCount > byData.Length)
                    {
                        throw new Exception("图片容量异常格式 : " + imgByCount);
                    }

                    byte[] byGvrData = new byte[0x20 + imgByCount];
                    Array.Copy(byData, i - 0x10, byGvrData, 0, byGvrData.Length);

                    string imgFileInfo = Util.GetShortName(file) + " " + (i - 0x10).ToString("x") + "--" + (i - 0x10 + byGvrData.Length).ToString("x");
                    imgList.Add(byGvrData);
                    imgInfos.Add(imgFileInfo);

                    // 取得调色板大小
                    if (dataCodec.NeedsExternalPalette)
                    {
                        int    paletteCount     = dataCodec.PaletteEntries * byCountPalette;
                        byte[] byPalette        = new byte[paletteCount + 0x10];
                        int    paletteDataStart = i - 0x30;
                        if (byData[paletteDataStart] == 0x50 && byData[paletteDataStart + 1] == 0x50 &&
                            byData[paletteDataStart + 2] == 0x56 && byData[paletteDataStart + 3] == 0x52)
                        {
                            paletteDataStart = i - 0x20 - paletteCount - 0x10 - 0x20;
                        }
                        else
                        {
                            paletteDataStart = i - 0x20 - paletteCount - 0x10;
                        }
                        Array.Copy(byData, paletteDataStart, byPalette, 0, byPalette.Length);

                        this.paletteData.Add(imgFileInfo + " " + paletteDataStart.ToString(), byPalette);
                    }
                }
            }

            return(imgList);
        }
Example #29
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;
        }
Example #30
0
 /// <summary>
 /// Opens a texture to encode from a stream.
 /// </summary>
 /// <param name="source">Stream that contains the texture data.</param>
 /// <param name="length">Number of bytes to read.</param>
 /// <param name="pixelFormat">Pixel format to encode the texture to.</param>
 /// <param name="dataFormat">Data format to encode the texture to.</param>
 public PvrTextureEncoder(Stream source, int length, PvrPixelFormat pixelFormat, PvrDataFormat dataFormat)
     : base(source, length)
 {
     if (decodedBitmap != null)
     {
         initalized = Initalize(pixelFormat, dataFormat);
     }
 }
Example #31
0
        static void Main(string[] args)
        {
            ArchiveFromFolderMode folderMode;
            string        dir;
            string        filePath;
            string        directoryName;
            ArchiveBase   pvmArchive;
            ArchiveWriter pvmWriter;
            string        archiveName;
            string        path;

            byte[] filedata;
            bool   isPRS;
            bool   isBIN = false;
            string extension;

            // Usage
            if (args.Length == 0)
            {
                Console.WriteLine("ArchiveTool is a command line tool to extract and create PVM, GVM, PRS, DAT and PB archives.\nIt can also decompress SADX Gamecube 'SaCompGC' REL files.\n");
                Console.WriteLine("Usage:\n");
                Console.WriteLine("Extracting a PVM/GVM/PRS/PB/PVMX/DAT/REL file:\nArchiveTool <archivefile>\nIf the archive is PRS compressed, it will be decompressed first.\nIf the archive contains textures/sounds, the program will extract them and create a list of files named 'index.txt'.\n");
                Console.WriteLine("Extracting an NjUtil archive: ArchiveTool -nju <archivefile>\n");
                Console.WriteLine("Converting PVM/GVM to a folder texture pack: ArchiveTool -png <archivefile>\n");
                Console.WriteLine("Creating a PB archive from a folder with textures: ArchiveTool -pb <foldername>");
                Console.WriteLine("Creating a PVM/GVM/DAT/PVMX from a folder with textures/sounds: ArchiveTool <foldername> [-prs]\nThe program will create an archive from files listed in 'index.txt' in the folder.\nThe -prs option will make the program output a PRS compressed archive.\n");
                Console.WriteLine("Creating a PVM from PNG textures: ArchiveTool -pvm <folder> [-prs]\nThe texture list 'index.txt' must contain global indices listed before each texture filename for this option to work.\n");
                Console.WriteLine("Converting GVM to PVM (lossy): ArchiveTool -gvm2pvm <file.gvm> [-prs]\n");
                Console.WriteLine("Creating a PRS compressed binary: ArchiveTool <file.bin>\nFile extension must be .BIN for this option to work.\n");
                Console.WriteLine("Press ENTER to exit.");
                Console.ReadLine();
                return;
            }
            switch (args[0].ToLowerInvariant())
            {
            // GVM2PVM mode
            case "-gvm2pvm":
                filePath = args[1];
                isPRS    = false;
                if (args.Length > 2 && args[2] == "-prs")
                {
                    isPRS = true;
                }
                Console.WriteLine("Converting GVM to PVM: {0}", filePath);
                directoryName = Path.GetDirectoryName(filePath);
                extension     = Path.GetExtension(filePath).ToLowerInvariant();
                if (!File.Exists(filePath))
                {
                    Console.WriteLine("Supplied GVM archive does not exist!");
                    Console.WriteLine("Press ENTER to exit.");
                    Console.ReadLine();
                    return;
                }
                if (extension != ".gvm")
                {
                    Console.WriteLine("GVM2PVM mode can only be used with GVM files.");
                    Console.WriteLine("Press ENTER to exit.");
                    Console.ReadLine();
                    return;
                }
                path = Path.Combine(directoryName, Path.GetFileNameWithoutExtension(filePath));
                Directory.CreateDirectory(path);
                filedata = File.ReadAllBytes(filePath);
                using (TextWriter texList = File.CreateText(Path.Combine(path, Path.GetFileName(path) + ".txt")))
                {
                    try
                    {
                        ArchiveBase gvmfile = null;
                        byte[]      gvmdata = File.ReadAllBytes(filePath);
                        gvmfile = new GvmArchive();
                        ArchiveReader gvmReader = gvmfile.Open(gvmdata);
                        Stream        pvmStream = File.Open(Path.ChangeExtension(filePath, ".pvm"), FileMode.Create);
                        pvmArchive = new PvmArchive();
                        pvmWriter  = pvmArchive.Create(pvmStream);
                        foreach (ArchiveEntry file in gvmReader.Entries)
                        {
                            if (!File.Exists(Path.Combine(path, file.Name)))
                            {
                                gvmReader.ExtractToFile(file, Path.Combine(path, file.Name));
                            }
                            Stream    data        = File.Open(Path.Combine(path, file.Name), FileMode.Open);
                            VrTexture vrfile      = new GvrTexture(data);
                            Bitmap    tempTexture = vrfile.ToBitmap();
                            System.Drawing.Imaging.BitmapData bmpd = tempTexture.LockBits(new Rectangle(Point.Empty, tempTexture.Size), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                            int    stride = bmpd.Stride;
                            byte[] bits   = new byte[Math.Abs(stride) * bmpd.Height];
                            System.Runtime.InteropServices.Marshal.Copy(bmpd.Scan0, bits, 0, bits.Length);
                            tempTexture.UnlockBits(bmpd);
                            int tlevels = 0;
                            archiveName = Path.GetFileNameWithoutExtension(filePath);
                            for (int y = 0; y < tempTexture.Height; y++)
                            {
                                int srcaddr = y * Math.Abs(stride);
                                for (int x = 0; x < tempTexture.Width; x++)
                                {
                                    Color c = Color.FromArgb(BitConverter.ToInt32(bits, srcaddr + (x * 4)));
                                    if (c.A == 0)
                                    {
                                        tlevels = 1;
                                    }
                                    else if (c.A < 255)
                                    {
                                        tlevels = 2;
                                        break;
                                    }
                                }
                                if (tlevels == 2)
                                {
                                    break;
                                }
                            }
                            PvrPixelFormat ppf = PvrPixelFormat.Rgb565;
                            if (tlevels == 1)
                            {
                                ppf = PvrPixelFormat.Argb1555;
                            }
                            else if (tlevels == 2)
                            {
                                ppf = PvrPixelFormat.Argb4444;
                            }
                            PvrDataFormat pdf;
                            if (!vrfile.HasMipmaps)
                            {
                                if (tempTexture.Width == tempTexture.Height)
                                {
                                    pdf = PvrDataFormat.SquareTwiddled;
                                }
                                else
                                {
                                    pdf = PvrDataFormat.Rectangle;
                                }
                            }
                            else
                            {
                                if (tempTexture.Width == tempTexture.Height)
                                {
                                    pdf = PvrDataFormat.SquareTwiddledMipmaps;
                                }
                                else
                                {
                                    pdf = PvrDataFormat.RectangleTwiddled;
                                }
                            }
                            PvrTextureEncoder encoder = new PvrTextureEncoder(tempTexture, ppf, pdf);
                            encoder.GlobalIndex = vrfile.GlobalIndex;
                            string pvrPath = Path.ChangeExtension(Path.Combine(path, file.Name), ".pvr");
                            if (!File.Exists(pvrPath))
                            {
                                encoder.Save(pvrPath);
                            }
                            data.Close();
                            File.Delete(Path.Combine(path, file.Name));
                            pvmWriter.CreateEntryFromFile(pvrPath);
                            texList.WriteLine(Path.GetFileName(pvrPath));
                            Console.WriteLine("Adding texture {0}", pvrPath);
                        }
                        pvmWriter.Flush();
                        pvmStream.Flush();
                        pvmStream.Close();
                        if (isPRS)
                        {
                            Console.WriteLine("Compressing to PRS...");
                            byte[] pvmdata = File.ReadAllBytes(Path.ChangeExtension(filePath, ".pvm"));
                            pvmdata = FraGag.Compression.Prs.Compress(pvmdata);
                            File.WriteAllBytes(Path.ChangeExtension(filePath, ".PVM.PRS"), pvmdata);
                            File.Delete(Path.ChangeExtension(filePath, ".PVM"));
                        }
                        Console.WriteLine("Archive converted!");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Exception thrown: {0}", ex.ToString());
                        Console.WriteLine("Press ENTER to exit.");
                        Console.ReadLine();
                        return;
                    }
                }
                break;

            // CompilePVM mode
            case "-pvm":
                bool IsPRS = false;
                if (args[args.Length - 1] == "-prs")
                {
                    IsPRS = true;
                }
                filePath = args[1];
                string            FullLine;
                string            texturename;
                uint              GBIX             = 0;
                List <string>     textureNames     = new List <String>();
                List <PvrTexture> finalTextureList = new List <PvrTexture>();
                directoryName = Path.GetDirectoryName(filePath);
                archiveName   = Path.GetFileNameWithoutExtension(filePath);
                if (Directory.Exists(filePath))
                {
                    Console.WriteLine("Converting texture pack to PVM: {0}", filePath);
                    StreamReader texlistStream = File.OpenText(Path.Combine(filePath, "index.txt"));
                    while (!texlistStream.EndOfStream)
                    {
                        textureNames.Add(texlistStream.ReadLine());
                    }
                    pvmArchive = new PvmArchive();
                    Stream pvmStream = File.Open(Path.ChangeExtension(filePath, ".pvm"), FileMode.Create);
                    pvmWriter = (PvmArchiveWriter)pvmArchive.Create(pvmStream);
                    // Reading in textures
                    for (uint imgIndx = 0; imgIndx < textureNames.Count; imgIndx++)
                    {
                        FullLine = textureNames[(int)imgIndx];
                        if (string.IsNullOrEmpty(FullLine))
                        {
                            continue;
                        }
                        String[] substrings = FullLine.Split(',');
                        GBIX        = UInt32.Parse(substrings[0]);
                        texturename = substrings[1];
                        Bitmap tempTexture = new Bitmap(8, 8);
                        string texturePath = Path.Combine(filePath, Path.ChangeExtension(texturename, ".png"));
                        if (File.Exists(texturePath))
                        {
                            Console.WriteLine("Adding texture: " + (texturePath));
                            tempTexture = (Bitmap)Bitmap.FromFile(texturePath);
                            tempTexture = tempTexture.Clone(new Rectangle(Point.Empty, tempTexture.Size), System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                        }
                        else
                        {
                            Console.WriteLine(String.Concat("Texture ", textureNames[(int)imgIndx], " not found. Generating a placeholder. Check your files."));
                        }

                        System.Drawing.Imaging.BitmapData bmpd = tempTexture.LockBits(new Rectangle(Point.Empty, tempTexture.Size), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                        int    stride = bmpd.Stride;
                        byte[] bits   = new byte[Math.Abs(stride) * bmpd.Height];
                        System.Runtime.InteropServices.Marshal.Copy(bmpd.Scan0, bits, 0, bits.Length);
                        tempTexture.UnlockBits(bmpd);
                        int tlevels = 0;
                        for (int y = 0; y < tempTexture.Height; y++)
                        {
                            int srcaddr = y * Math.Abs(stride);
                            for (int x = 0; x < tempTexture.Width; x++)
                            {
                                Color c = Color.FromArgb(BitConverter.ToInt32(bits, srcaddr + (x * 4)));
                                if (c.A == 0)
                                {
                                    tlevels = 1;
                                }
                                else if (c.A < 255)
                                {
                                    tlevels = 2;
                                    break;
                                }
                            }
                            if (tlevels == 2)
                            {
                                break;
                            }
                        }
                        PvrPixelFormat ppf = PvrPixelFormat.Rgb565;
                        if (tlevels == 1)
                        {
                            ppf = PvrPixelFormat.Argb1555;
                        }
                        else if (tlevels == 2)
                        {
                            ppf = PvrPixelFormat.Argb4444;
                        }
                        PvrDataFormat pdf = PvrDataFormat.Rectangle;
                        if (tempTexture.Width == tempTexture.Height)
                        {
                            pdf = PvrDataFormat.SquareTwiddled;
                        }
                        PvrTextureEncoder encoder = new PvrTextureEncoder(tempTexture, ppf, pdf);
                        encoder.GlobalIndex = GBIX;
                        string pvrPath = Path.ChangeExtension(texturePath, ".pvr");
                        encoder.Save(pvrPath);
                        pvmWriter.CreateEntryFromFile(pvrPath);
                    }
                    pvmWriter.Flush();
                    pvmStream.Close();
                    if (IsPRS)
                    {
                        Console.WriteLine("Compressing to PRS...");
                        byte[] pvmdata = File.ReadAllBytes(Path.ChangeExtension(filePath, ".pvm"));
                        pvmdata = FraGag.Compression.Prs.Compress(pvmdata);
                        File.WriteAllBytes(Path.ChangeExtension(filePath, ".prs"), pvmdata);
                        File.Delete(Path.ChangeExtension(filePath, ".pvm"));
                    }
                    Console.WriteLine("Archive was compiled successfully!");
                }
                else
                {
                    Console.WriteLine("Supplied texture list does not exist!");
                    Console.WriteLine("Press ENTER to continue...");
                    Console.ReadLine();
                    return;
                }
                break;

            // Create PB mode
            case "-pb":
                filePath = args[1];
                Console.WriteLine("Building PB from folder: {0}", filePath);
                if (Directory.Exists(filePath))
                {
                    string indexfilename = Path.Combine(filePath, "index.txt");
                    if (!File.Exists(indexfilename))
                    {
                        Console.WriteLine("Supplied path does not have an index file.");
                        Console.WriteLine("Press ENTER to exit.");
                        Console.ReadLine();
                        return;
                    }
                    List <string> filenames = new List <string>(File.ReadAllLines(indexfilename).Where(a => !string.IsNullOrEmpty(a)));
                    PBFile        pba       = new PBFile(filenames.Count);
                    int           l         = 0;
                    foreach (string tex in filenames)
                    {
                        byte[] texbytes = File.ReadAllBytes(Path.Combine(filePath, tex));
                        pba.AddPVR(texbytes, l);
                        l++;
                    }
                    path = Path.Combine(Path.GetDirectoryName(Path.GetFullPath(filePath)), Path.GetFileNameWithoutExtension(filePath));
                    string filename_full = Path.Combine(Path.GetDirectoryName(Path.GetFullPath(filePath)), Path.GetFileName(filePath) + ".pb");
                    Console.WriteLine("Output file: {0}", filename_full);
                    File.WriteAllBytes(filename_full, pba.GetBytes());
                }
                else
                {
                    Console.WriteLine("Supplied path does not exist.");
                    Console.WriteLine("Press ENTER to exit.");
                    Console.ReadLine();
                    return;
                }
                break;

            // Extract NjArchive mode
            case "-nju":
                filePath = args[1];
                filedata = File.ReadAllBytes(filePath);
                if (Path.GetExtension(filePath).Equals(".prs", StringComparison.OrdinalIgnoreCase))
                {
                    filedata = FraGag.Compression.Prs.Decompress(filedata);
                }
                NjArchive njarc = new NjArchive(filedata);
                Console.WriteLine("Extracting Ninja archive: {0}", filePath);
                dir = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath));
                Console.WriteLine("Output folder: {0}", dir);
                Directory.CreateDirectory(dir);
                for (int i = 0; i < njarc.Entries.Count; i++)
                {
                    byte[] data = njarc.Entries[i];
                    extension = ".bin";
                    string desc = "Unknown";
                    switch (System.Text.Encoding.ASCII.GetString(data, 0, 4))
                    {
                    case "NJIN":
                        desc      = "Ninja Information";
                        extension = ".nji";
                        break;

                    case "NJCM":
                        desc      = "Ninja Chunk model";
                        extension = ".nj";
                        break;

                    case "GJCM":
                        desc      = "Ninja Chunk model (GC)";
                        extension = ".gj";
                        break;

                    case "NJBM":
                        desc      = "Ninja Basic model";
                        extension = ".nj";
                        break;

                    case "NMDM":
                        desc      = "Ninja Motion";
                        extension = ".njm";
                        break;

                    case "NJLI":
                        desc      = "Ninja Light";
                        extension = ".njl";
                        break;

                    case "NLIM":
                        desc      = "Ninja Light Motion";
                        extension = ".njlm";
                        break;

                    case "NSSM":
                        desc      = "Ninja Simple Shape Motion";
                        extension = ".njsm";
                        break;

                    case "NCAM":
                        desc      = "Ninja Camera Motion";
                        extension = ".ncm";
                        break;

                    case "NJTL":
                        desc      = "Ninja Texlist";
                        extension = ".nj";
                        break;

                    case "GJTL":
                        desc      = "Ninja Texlist (GC)";
                        extension = ".gj";
                        break;

                    case "PVMH":
                        desc      = "PVM";
                        extension = ".pvm";
                        break;

                    case "GVMH":
                        desc      = "GVM";
                        extension = ".gvm";
                        break;
                    }
                    Console.WriteLine("Entry {0} is {1}", i, desc);
                    string outpath = Path.Combine(dir, i.ToString("D3") + extension);
                    File.WriteAllBytes(outpath, njarc.Entries[i]);
                }
                break;

            // PVM2TexPack mode
            case "-png":
                Queue <string> files = new Queue <string>();
                for (int u = 1; u < args.Length; u++)
                {
                    files.Enqueue(args[u]);
                }
                if (files.Count == 0)
                {
                    Console.Write("File: ");
                    files.Enqueue(Console.ReadLine());
                }
                while (files.Count > 0)
                {
                    string filename = files.Dequeue();
                    path = Path.Combine(Path.GetDirectoryName(Path.GetFullPath(filename)), Path.GetFileNameWithoutExtension(filename));
                    string filename_full = Path.Combine(Path.GetDirectoryName(Path.GetFullPath(filename)), Path.GetFileName(filename));
                    Console.WriteLine("Converting file to texture pack: {0}", filename_full);
                    Directory.CreateDirectory(path);
                    filedata = File.ReadAllBytes(filename_full);
                    using (TextWriter texList = File.CreateText(Path.Combine(path, "index.txt")))
                    {
                        try
                        {
                            if (PvrTexture.Is(filedata))
                            {
                                if (!AddTexture(false, path, Path.GetFileName(filename_full), new MemoryStream(filedata), texList))
                                {
                                    texList.Close();
                                    Directory.Delete(path, true);
                                }
                                continue;
                            }
                            else if (GvrTexture.Is(filedata))
                            {
                                if (!AddTexture(true, path, Path.GetFileName(filename_full), new MemoryStream(filedata), texList))
                                {
                                    texList.Close();
                                    Directory.Delete(path, true);
                                }
                                continue;
                            }
                            bool        gvm     = false;
                            ArchiveBase pvmfile = null;
                            byte[]      pvmdata = File.ReadAllBytes(filename_full);
                            if (Path.GetExtension(filename_full).Equals(".prs", StringComparison.OrdinalIgnoreCase))
                            {
                                pvmdata = FraGag.Compression.Prs.Decompress(pvmdata);
                            }
                            pvmfile = new PvmArchive();
                            MemoryStream stream = new MemoryStream(pvmdata);
                            if (!PvmArchive.Identify(stream))
                            {
                                pvmfile = new GvmArchive();
                                gvm     = true;
                            }
                            ArchiveEntryCollection pvmentries = pvmfile.Open(pvmdata).Entries;
                            bool fail = false;
                            foreach (ArchiveEntry file in pvmentries)
                            {
                                if (!AddTexture(gvm, path, file.Name, file.Open(), texList))
                                {
                                    texList.Close();
                                    Directory.Delete(path, true);
                                    fail = true;
                                    break;
                                }
                            }
                            if (fail)
                            {
                                continue;
                            }
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("Exception thrown: " + ex.ToString() + "\nCanceling conversion.");
                            return;
                        }
                        Console.WriteLine("Conversion complete!");
                    }
                }
                break;

            // Other modes
            default:
                filePath = args[0];
                IsPRS    = false;
                if (args.Length > 1 && args[1] == "-prs")
                {
                    IsPRS = true;
                }
                extension = Path.GetExtension(filePath).ToLowerInvariant();
                //Folder mode
                if (Directory.Exists(filePath))
                {
                    string        indexfilename = Path.Combine(filePath, "index.txt");
                    List <string> filenames     = new List <string>(File.ReadAllLines(indexfilename).Where(a => !string.IsNullOrEmpty(a)));
                    string        ext           = Path.GetExtension(filenames[0]).ToLowerInvariant();
                    pvmArchive = new PvmArchive();
                    switch (ext)
                    {
                    case ".pvr":
                        folderMode = ArchiveFromFolderMode.PVM;
                        break;

                    case ".gvr":
                        pvmArchive = new GvmArchive();
                        folderMode = ArchiveFromFolderMode.GVM;
                        break;

                    case ".wav":
                        folderMode = ArchiveFromFolderMode.DAT;
                        break;

                    case ".png":
                    case ".jpg":
                    case ".bmp":
                    case ".dds":
                    case ".gif":
                    default:
                        folderMode = ArchiveFromFolderMode.PVMX;
                        break;
                    }
                    Console.WriteLine("Creating {0} archive from folder: {1}", folderMode.ToString(), filePath);
                    switch (folderMode)
                    {
                    case ArchiveFromFolderMode.DAT:
                        // Load index
                        DATFile    dat  = new DATFile();
                        TextReader tr   = File.OpenText(Path.Combine(filePath, "index.txt"));
                        string     line = tr.ReadLine();
                        while (line != null)
                        {
                            Console.WriteLine("Adding file {0}", Path.Combine(filePath, line));
                            dat.AddFile(Path.Combine(filePath, line));
                            line = tr.ReadLine();
                        }
                        tr.Close();
                        // Save DAT archive
                        File.WriteAllBytes(filePath + ".DAT", dat.GetBytes());
                        if (IsPRS)
                        {
                            Console.WriteLine("Compressing to PRS...");
                            byte[] datdata = File.ReadAllBytes(filePath + ".DAT");
                            datdata = FraGag.Compression.Prs.Compress(datdata);
                            File.WriteAllBytes(filePath + ".PRS", datdata);
                            File.Delete(filePath + ".DAT");
                        }
                        Console.WriteLine("Archive compiled successfully!");
                        return;

                    case ArchiveFromFolderMode.PVM:
                    case ArchiveFromFolderMode.GVM:
                        if (filenames.Any(a => !Path.GetExtension(a).Equals(ext, StringComparison.OrdinalIgnoreCase)))
                        {
                            Console.WriteLine("Cannot create archive from mixed file types.");
                            Console.WriteLine("Press ENTER to exit.");
                            Console.ReadLine();
                            return;
                        }
                        ext = folderMode == ArchiveFromFolderMode.PVM ? ".pvm" : ".gvm";
                        using (Stream pvmStream = File.Open(Path.ChangeExtension(filePath, ext), FileMode.Create))
                        {
                            pvmWriter = pvmArchive.Create(pvmStream);
                            // Reading in textures
                            foreach (string tex in filenames)
                            {
                                if (folderMode == ArchiveFromFolderMode.PVM)
                                {
                                    pvmWriter.CreateEntryFromFile(Path.Combine(filePath, Path.ChangeExtension(tex, ".pvr")));
                                }
                                else
                                {
                                    pvmWriter.CreateEntryFromFile(Path.Combine(filePath, Path.ChangeExtension(tex, ".gvr")));
                                }
                                Console.WriteLine("Adding file: {0}", tex);
                            }
                            pvmWriter.Flush();
                        }
                        if (IsPRS)
                        {
                            Console.WriteLine("Compressing to PRS...");
                            byte[] pvmdata = File.ReadAllBytes(Path.ChangeExtension(filePath, ext));
                            pvmdata = FraGag.Compression.Prs.Compress(pvmdata);
                            File.WriteAllBytes(Path.ChangeExtension(filePath, ".prs"), pvmdata);
                            File.Delete(Path.ChangeExtension(filePath, ext));
                        }
                        Console.WriteLine("Archive was compiled successfully!");
                        return;

                    case ArchiveFromFolderMode.PVMX:
                        // Load index
                        PVMXFile   pvmx = new PVMXFile();
                        TextReader trp  = File.OpenText(Path.Combine(filePath, "index.txt"));
                        foreach (string str in filenames)
                        {
                            string[] split   = str.Split(',');
                            string   texfile = Path.Combine(Path.GetFullPath(filePath), split[1]);
                            Console.WriteLine("Adding file {0}", texfile);
                            if (split.Length > 2)
                            {
                                string[] dimensions = split[2].Split('x');
                                pvmx.AddFile(split[1], uint.Parse(split[0]), File.ReadAllBytes(texfile), int.Parse(dimensions[0]), int.Parse(dimensions[1]));
                            }
                            else
                            {
                                pvmx.AddFile(split[1], uint.Parse(split[0]), File.ReadAllBytes(texfile));
                            }
                        }
                        Console.WriteLine("Output file: {0}", Path.ChangeExtension(filePath, ".pvmx"));
                        File.WriteAllBytes(Path.ChangeExtension(filePath, ".pvmx"), pvmx.GetBytes());
                        Console.WriteLine("Archive was compiled successfully!");
                        return;
                    }
                }
                //Continue with file mode otherwise
                if (!File.Exists(filePath))
                {
                    Console.WriteLine("Supplied archive/texture list does not exist!");
                    Console.WriteLine("Press ENTER to exit.");
                    Console.ReadLine();
                    return;
                }
                switch (extension)
                {
                case ".rel":
                    Console.WriteLine("Decompressing REL file: {0}", filePath);
                    byte[] input  = File.ReadAllBytes(args[0]);
                    byte[] output = SA_Tools.HelperFunctions.DecompressREL(input);
                    File.WriteAllBytes(Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath) + "_dec.rel"), output);
                    return;

                case ".dat":
                    Console.WriteLine("Extracting DAT file: {0}", filePath);
                    DATFile dat = new DATFile(File.ReadAllBytes(filePath));
                    dir = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath));
                    if (Directory.Exists(dir))
                    {
                        Directory.Delete(dir, true);
                    }
                    Directory.CreateDirectory(dir);
                    using (StreamWriter sw = File.CreateText(Path.Combine(dir, "index.txt")))
                    {
                        dat.Entries.Sort((f1, f2) => StringComparer.OrdinalIgnoreCase.Compare(f1.name, f2.name));
                        for (int i = 0; i < dat.GetCount(); i++)
                        {
                            string fname = dat.Entries[i].name;
                            sw.WriteLine(fname);
                            if (dat.Steam)
                            {
                                fname = Path.GetFileNameWithoutExtension(fname) + ".adx";
                            }
                            Console.WriteLine("Extracting file: {0}", fname);
                            File.WriteAllBytes(Path.Combine(dir, fname), dat.GetFile(i));
                        }
                        sw.Flush();
                        sw.Close();
                    }
                    Console.WriteLine("Archive extracted!");
                    break;

                case ".pvmx":
                    Console.WriteLine("Extracting PVMX file: {0}", filePath);
                    byte[] pvmxdata = File.ReadAllBytes(filePath);
                    dir = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath));
                    Directory.CreateDirectory(dir);
                    PVMXFile pvmx = new PVMXFile(pvmxdata);
                    using (TextWriter texList = File.CreateText(Path.Combine(dir, "index.txt")))
                    {
                        for (int u = 0; u < pvmx.GetCount(); u++)
                        {
                            byte[] tdata   = pvmx.GetFile(u);
                            string outpath = Path.Combine(dir, pvmx.GetName(u));
                            File.WriteAllBytes(outpath, tdata);
                            string entry;
                            string dimensions = string.Join("x", pvmx.GetWidth(u).ToString(), pvmx.GetHeight(u).ToString());
                            if (pvmx.HasDimensions(u))
                            {
                                entry = string.Join(",", pvmx.GetGBIX(u).ToString(), pvmx.GetName(u), dimensions);
                            }
                            else
                            {
                                entry = string.Join(",", pvmx.GetGBIX(u).ToString(), pvmx.GetName(u));
                            }
                            texList.WriteLine(entry);
                        }
                        texList.Flush();
                        texList.Close();
                    }
                    Console.WriteLine("Archive extracted!");
                    break;

                case ".pb":
                    Console.WriteLine("Extracting PB file: {0}", filePath);
                    byte[] pbdata = File.ReadAllBytes(filePath);
                    dir = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath));
                    Directory.CreateDirectory(dir);
                    PBFile pba = new PBFile(pbdata);
                    using (TextWriter texList = File.CreateText(Path.Combine(dir, "index.txt")))
                    {
                        for (int u = 0; u < pba.GetCount(); u++)
                        {
                            byte[] pvrt    = pba.GetPVR(u);
                            string outpath = Path.Combine(dir, u.ToString("D3") + ".pvr");
                            File.WriteAllBytes(outpath, pvrt);
                            texList.WriteLine(u.ToString("D3") + ".pvr");
                        }
                        texList.Flush();
                        texList.Close();
                    }
                    Console.WriteLine("Archive extracted!");
                    break;

                case ".bin":
                    Console.WriteLine("Compressing BIN file: {0}", filePath);
                    byte[] bindata = File.ReadAllBytes(Path.ChangeExtension(filePath, ".bin"));
                    bindata = FraGag.Compression.Prs.Compress(bindata);
                    File.WriteAllBytes(Path.ChangeExtension(filePath, ".prs"), bindata);
                    Console.WriteLine("PRS archive was compiled successfully!");
                    return;

                case ".prs":
                case ".pvm":
                case ".gvm":
                    Console.WriteLine("Extracting archive: {0}", filePath);
                    path = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath));
                    Directory.CreateDirectory(path);
                    filedata = File.ReadAllBytes(filePath);
                    using (TextWriter texList = File.CreateText(Path.Combine(path, "index.txt")))
                    {
                        try
                        {
                            ArchiveBase pvmfile = null;
                            byte[]      pvmdata = File.ReadAllBytes(filePath);
                            if (extension == ".prs")
                            {
                                pvmdata = FraGag.Compression.Prs.Decompress(pvmdata);
                            }
                            pvmfile = new PvmArchive();
                            MemoryStream stream = new MemoryStream(pvmdata);
                            if (!PvmArchive.Identify(stream))
                            {
                                pvmfile = new GvmArchive();
                                if (!GvmArchive.Identify(stream))
                                {
                                    File.WriteAllBytes(Path.ChangeExtension(filePath, ".bin"), pvmdata);
                                    isBIN = true;
                                    Console.WriteLine("PRS archive extracted!");
                                }
                            }
                            if (!isBIN)
                            {
                                ArchiveReader pvmReader = pvmfile.Open(pvmdata);
                                foreach (ArchiveEntry pvmentry in pvmReader.Entries)
                                {
                                    Console.WriteLine("Extracting file: {0}", pvmentry.Name);
                                    texList.WriteLine(pvmentry.Name);
                                    pvmReader.ExtractToFile(pvmentry, Path.Combine(path, pvmentry.Name));
                                }
                                Console.WriteLine("Archive extracted!");
                            }
                        }
                        catch
                        {
                            Console.WriteLine("Exception thrown. Canceling conversion.");
                            Console.WriteLine("Press ENTER to exit.");
                            Console.ReadLine();
                            Directory.Delete(path, true);
                            throw;
                        }
                    }
                    if (isBIN)
                    {
                        Directory.Delete(path, true);
                    }
                    break;

                default:
                    Console.WriteLine("Unknown extension \"{0}\".", extension);
                    Console.WriteLine("Press ENTER to exit.");
                    Console.ReadLine();
                    break;
                }
                break;
            }
        }
Example #32
0
        private static string DataFormatToString(PvrDataFormat format)
        {
            switch (format)
            {
                case PvrDataFormat.SquareTwiddled:           return "Square Twiddled";
                case PvrDataFormat.SquareTwiddledMipmaps:    return "Square Twiddled with Mipmaps";
                case PvrDataFormat.Vq:                       return "VQ";
                case PvrDataFormat.VqMipmaps:                return "VQ with Mipmaps";
                case PvrDataFormat.Index4:                   return "4-bit Indexed with External Palette";
                case PvrDataFormat.Index8:                   return "8-bit Indexed with External Palette";
                case PvrDataFormat.Rectangle:                return "Rectangle";
                case PvrDataFormat.RectangleTwiddled:        return "Rectangle Twiddled";
                case PvrDataFormat.SmallVq:                  return "Small VQ";
                case PvrDataFormat.SmallVqMipmaps:           return "Small VQ with Mipmaps";
                case PvrDataFormat.SquareTwiddledMipmapsAlt: return "Square Twiddled with Mipmaps (Alternate)";
            }

            return "Unknown";
        }