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()); }
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)); }
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); }
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); }
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);
// 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)); }
// Decode texture data public virtual byte[] Decode(byte[] input, int offset, int width, int height, PvrPixelCodec PixelCodec) { return(Decode(input, offset, width, height)); }