public override byte[] Decompress(byte[] input, int DataOffset, PvrPixelCodec PixelCodec, PvrDataCodec DataCodec)
            {
                byte[] output        = new byte[BitConverter.ToUInt32(input, 0x00)];
                int    SourcePointer = DataOffset;
                int    DestPointer   = 0x00;
                int    PixelSize     = (DataCodec.Bpp >> 3);

                // Copy the header
                if (DataOffset - 4 > 0)
                {
                    Array.Copy(input, 0x04, output, 0x00, DataOffset - 4);
                    DestPointer += (DataOffset - 4);
                }

                // Decompress
                while (SourcePointer < input.Length && DestPointer < output.Length)
                {
                    int amount = input[SourcePointer + PixelSize] + 1;
                    for (int i = 0; i < amount; i++)
                    {
                        Array.Copy(input, SourcePointer, output, DestPointer, PixelSize);
                        DestPointer += PixelSize;
                    }

                    SourcePointer += PixelSize + 1;
                }

                return(output);
            }
        private PvrPixelFormat m_pixelFormat; // Pixel format

        public PvpPaletteEncoder(byte[][] palette, ushort numColors, PvrPixelFormat pixelFormat, PvrPixelCodec pixelCodec)
        {
            m_decodedPalette = palette;
            m_paletteEntries = numColors;
            m_pixelCodec     = pixelCodec;
            m_pixelFormat    = pixelFormat;
        }
            public override byte[] Compress(byte[] input, int DataOffset, PvrPixelCodec PixelCodec, PvrDataCodec DataCodec)
            {
                // We can't compress 4-bit textures
                if (DataCodec.Bpp < 8)
                {
                    return(input);
                }

                MemoryStream output        = new MemoryStream();
                int          SourcePointer = DataOffset;
                int          DestPointer   = DataOffset + 4;
                int          PixelSize     = (DataCodec.Bpp >> 3);

                using (BinaryWriter Writer = new BinaryWriter(output))
                {
                    Writer.Write(input.Length);            // Decompressed filesize
                    Writer.Write(input, 0x00, DataOffset); // Header

                    while (SourcePointer < input.Length)
                    {
                        byte[] pixel = new byte[PixelSize];
                        Array.Copy(input, SourcePointer, pixel, 0x00, PixelSize);
                        Writer.Write(pixel);
                        SourcePointer += PixelSize;
                        DestPointer   += PixelSize;

                        int repeat = 0;
                        while (SourcePointer + PixelSize < input.Length && repeat < 255)
                        {
                            bool match = true;

                            for (int i = 0; i < PixelSize && match; i++)
                            {
                                if (input[SourcePointer + i] != pixel[i])
                                {
                                    match = false;
                                    break;
                                }
                            }

                            if (match)
                            {
                                repeat++;
                                SourcePointer += PixelSize;
                            }
                            else
                            {
                                break;
                            }
                        }

                        Writer.Write((byte)repeat);
                        DestPointer++;
                    }

                    Writer.Flush();
                }

                return(output.ToArray());
            }
示例#4
0
        public byte[] Decode(BinaryReader reader, int width, int height, PvrPixelCodec pixelCodec)
        {
            double d = pixelCodec.Bpp / 8.0;

            byte[] data = reader.ReadBytes((int)(width * height * d));
            return(Decode(data, 0, width, height, pixelCodec));
        }
示例#5
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);
        }
示例#6
0
        public bool Initalize()
        {
            // Check to see if what we are dealing with is a GVP palette
            if (!Is(m_encodedData))
            {
                return(false);
            }

            // Get the pixel format and the codec and make sure we can decode using them
            m_pixelFormat = (PvrPixelFormat)m_encodedData[0x08];
            m_pixelCodec  = PvrPixelCodec.GetPixelCodec(m_pixelFormat);
            if (m_pixelCodec == null)
            {
                return(false);
            }

            // Get the number of colors contained in the palette
            m_paletteEntries = BitConverter.ToUInt16(m_encodedData, 0x0E);

            return(true);
        }
示例#7
0
        public void Initalize()
        {
            // Determine the offsets of the GBIX (if present) and PVRT header chunks.
            if (PTMethods.Contains(m_encodedData, 0x00, gbixFourCC))
            {
                GbixOffset = 0x00;
                PvrtOffset = 0x08 + BitConverter.ToInt32(m_encodedData, GbixOffset + 4);
            }
            else if (PTMethods.Contains(m_encodedData, 0x04, gbixFourCC))
            {
                GbixOffset = 0x04;
                PvrtOffset = 0x0C + BitConverter.ToInt32(m_encodedData, GbixOffset + 4);
            }
            else if (PTMethods.Contains(m_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(m_encodedData, GbixOffset + 0x08);
            }
            else
            {
                GlobalIndex = 0;
            }

            // Read information about the texture
            TextureWidth  = BitConverter.ToUInt16(m_encodedData, PvrtOffset + 0x0C);
            TextureHeight = BitConverter.ToUInt16(m_encodedData, PvrtOffset + 0x0E);

            PixelFormat = (PvrPixelFormat)m_encodedData[PvrtOffset + 0x08];
            DataFormat  = (PvrDataFormat)m_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;
            }

            // Set the number of palette entries
            // The number in a Small Vq encoded texture various based on its size
            m_paletteEntries = DataCodec.PaletteEntries;
            if (DataFormat == PvrDataFormat.VECTOR_QUANTIZATION_SMALL || DataFormat == PvrDataFormat.VECTOR_QUANTIZATION_SMALL_MIPMAP)
            {
                if (TextureWidth <= 16)
                {
                    m_paletteEntries = 64; // Actually 16
                }
                else if (TextureWidth <= 32)
                {
                    m_paletteEntries = 256; // Actually 64
                }
                else if (TextureWidth <= 64)
                {
                    m_paletteEntries = 512; // Actually 128
                }
                else
                {
                    m_paletteEntries = 1024; // Actually 256
                }
            }

            // Set the palette and data offsets
            if (m_paletteEntries == 0 || DataCodec.NeedsExternalPalette)
            {
                m_paletteOffset = -1;
                m_dataOffset    = PvrtOffset + 0x10;
            }
            else
            {
                m_paletteOffset = PvrtOffset + 0x10;
                m_dataOffset    = m_paletteOffset + (m_paletteEntries * (PixelCodec.Bpp >> 3));
            }

            // Get the compression format and determine if we need to decompress this texture
            CompressionFormat = GetCompressionFormat(m_encodedData, PvrtOffset, m_dataOffset);
            CompressionCodec  = PvrCompressionCodec.GetCompressionCodec(CompressionFormat);

            if (CompressionFormat != PvrCompressionFormat.NONE && CompressionCodec != null)
            {
                m_encodedData = CompressionCodec.Decompress(m_encodedData, m_dataOffset, PixelCodec, DataCodec);

                // Now place the offsets in the appropiate area
                if (CompressionFormat == PvrCompressionFormat.RLE)
                {
                    if (GbixOffset != -1)
                    {
                        GbixOffset -= 4;
                    }
                    PvrtOffset -= 4;
                    if (m_paletteOffset != -1)
                    {
                        m_paletteOffset -= 4;
                    }
                    m_dataOffset -= 4;
                }
            }

            // If the texture contains mipmaps, gets the offsets of them
            if (DataCodec.HasMipmaps)
            {
                m_mipmapOffsets = new int[(int)Math.Log(TextureWidth, 2) + 1];

                int mipmapOffset = 0;

                // Calculate the padding for the first mipmap offset
                if (DataFormat == PvrDataFormat.SQUARE_TWIDDLED_MIPMAP)
                {
                    // A 1x1 mipmap takes up as much space as a 2x1 mipmap
                    mipmapOffset = (DataCodec.Bpp) >> 3;
                }
                else if (DataFormat == PvrDataFormat.SQUARE_TWIDDLED_MIPMAP_ALT)
                {
                    // A 1x1 mipmap takes up as much space as a 2x2 mipmap
                    mipmapOffset = (3 * DataCodec.Bpp) >> 3;
                }

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

                    mipmapOffset += Math.Max((size * size * DataCodec.Bpp) >> 3, 1);
                }
            }
        }
 public abstract byte[] Compress(byte[] input, int DataOffset, PvrPixelCodec PixelCodec, PvrDataCodec DataCodec);
示例#9
0
 // Decode a mipmap in the texture data
 //public virtual byte[] DecodeMipmap(byte[] input, int offset, int mipmap, int width, int height, VrPixelCodec PixelCodec)
 //{
 //    return Decode(input, offset, width, height, PixelCodec);
 //}
 // Encode texture data
 public virtual byte[] Encode(byte[] input, int width, int height, PvrPixelCodec PixelCodec)
 {
     return(Encode(input, 0, width, height));
 }
示例#10
0
 // Decode texture data
 public virtual byte[] Decode(byte[] input, int offset, int width, int height, PvrPixelCodec PixelCodec)
 {
     return(Decode(input, offset, width, height));
 }