public static ClientMessage EncodeRequest(string name, IData key, IData @value, long threadId) { var clientMessage = CreateForEncode(); clientMessage.IsRetryable = false; clientMessage.OperationName = "Map.RemoveIfSame"; var initialFrame = new Frame(new byte[RequestInitialFrameSize], UnfragmentedMessage); EncodeInt(initialFrame.Content, TypeFieldOffset, RequestMessageType); EncodeInt(initialFrame.Content, PartitionIdFieldOffset, -1); EncodeLong(initialFrame.Content, RequestThreadIdFieldOffset, threadId); clientMessage.Add(initialFrame); StringCodec.Encode(clientMessage, name); DataCodec.Encode(clientMessage, key); DataCodec.Encode(clientMessage, @value); return(clientMessage); }
public static ClientMessage EncodeRequest(string name, IData entryProcessor, ICollection <IData> keys) { var clientMessage = new ClientMessage { IsRetryable = false, OperationName = "Map.ExecuteOnKeys" }; var initialFrame = new Frame(new byte[RequestInitialFrameSize], (FrameFlags)ClientMessageFlags.Unfragmented); initialFrame.Bytes.WriteIntL(Messaging.FrameFields.Offset.MessageType, RequestMessageType); initialFrame.Bytes.WriteIntL(Messaging.FrameFields.Offset.PartitionId, -1); clientMessage.Append(initialFrame); StringCodec.Encode(clientMessage, name); DataCodec.Encode(clientMessage, entryProcessor); ListMultiFrameCodec.Encode(clientMessage, keys, DataCodec.Encode); return(clientMessage); }
public static ClientMessage EncodeRequest(string name, IData key, long ttl) { var clientMessage = new ClientMessage { IsRetryable = false, OperationName = "Map.SetTtl" }; var initialFrame = new Frame(new byte[RequestInitialFrameSize], (FrameFlags)ClientMessageFlags.Unfragmented); initialFrame.Bytes.WriteIntL(Messaging.FrameFields.Offset.MessageType, RequestMessageType); initialFrame.Bytes.WriteIntL(Messaging.FrameFields.Offset.PartitionId, -1); initialFrame.Bytes.WriteLongL(RequestTtlFieldOffset, ttl); clientMessage.Append(initialFrame); StringCodec.Encode(clientMessage, name); DataCodec.Encode(clientMessage, key); return(clientMessage); }
public static ClientMessage EncodeRequest(string name, Guid txnId, long threadId, IData key) { var clientMessage = CreateForEncode(); clientMessage.IsRetryable = false; clientMessage.OperationName = "TransactionalMultiMap.Get"; var initialFrame = new Frame(new byte[RequestInitialFrameSize], UnfragmentedMessage); EncodeInt(initialFrame.Content, TypeFieldOffset, RequestMessageType); EncodeInt(initialFrame.Content, PartitionIdFieldOffset, -1); EncodeGuid(initialFrame.Content, RequestTxnIdFieldOffset, txnId); EncodeLong(initialFrame.Content, RequestThreadIdFieldOffset, threadId); clientMessage.Add(initialFrame); StringCodec.Encode(clientMessage, name); DataCodec.Encode(clientMessage, key); return(clientMessage); }
public static ClientMessage EncodeRequest(string name, IData key, bool includeValue, int listenerFlags, bool localOnly) { var clientMessage = CreateForEncode(); clientMessage.IsRetryable = false; clientMessage.OperationName = "Map.AddEntryListenerToKey"; var initialFrame = new Frame(new byte[RequestInitialFrameSize], UnfragmentedMessage); EncodeInt(initialFrame.Content, TypeFieldOffset, RequestMessageType); EncodeInt(initialFrame.Content, PartitionIdFieldOffset, -1); EncodeBool(initialFrame.Content, RequestIncludeValueFieldOffset, includeValue); EncodeInt(initialFrame.Content, RequestListenerFlagsFieldOffset, listenerFlags); EncodeBool(initialFrame.Content, RequestLocalOnlyFieldOffset, localOnly); clientMessage.Add(initialFrame); StringCodec.Encode(clientMessage, name); DataCodec.Encode(clientMessage, key); return(clientMessage); }
public static ClientMessage EncodeRequest(string name, Guid txnId, long threadId, IData key) { var clientMessage = new ClientMessage { IsRetryable = false, OperationName = "TransactionalMap.ContainsKey" }; var initialFrame = new Frame(new byte[RequestInitialFrameSize], (FrameFlags)ClientMessageFlags.Unfragmented); initialFrame.Bytes.WriteIntL(Messaging.FrameFields.Offset.MessageType, RequestMessageType); initialFrame.Bytes.WriteIntL(Messaging.FrameFields.Offset.PartitionId, -1); initialFrame.Bytes.WriteGuidL(RequestTxnIdFieldOffset, txnId); initialFrame.Bytes.WriteLongL(RequestThreadIdFieldOffset, threadId); clientMessage.Append(initialFrame); StringCodec.Encode(clientMessage, name); DataCodec.Encode(clientMessage, key); return(clientMessage); }
public static ClientMessage EncodeRequest(string name, IData key, bool includeValue, bool localOnly) { var clientMessage = new ClientMessage { IsRetryable = false, OperationName = "MultiMap.AddEntryListenerToKey" }; var initialFrame = new Frame(new byte[RequestInitialFrameSize], (FrameFlags)ClientMessageFlags.Unfragmented); initialFrame.Bytes.WriteIntL(Messaging.FrameFields.Offset.MessageType, RequestMessageType); initialFrame.Bytes.WriteIntL(Messaging.FrameFields.Offset.PartitionId, -1); initialFrame.Bytes.WriteBoolL(RequestIncludeValueFieldOffset, includeValue); initialFrame.Bytes.WriteBoolL(RequestLocalOnlyFieldOffset, localOnly); clientMessage.Append(initialFrame); StringCodec.Encode(clientMessage, name); DataCodec.Encode(clientMessage, key); return(clientMessage); }
public static ClientMessage EncodeRequest(string name, ICollection <KeyValuePair <int, int> > iterationPointers, int batch, IData projection, IData predicate) { var clientMessage = CreateForEncode(); clientMessage.IsRetryable = true; clientMessage.OperationName = "Map.FetchWithQuery"; var initialFrame = new Frame(new byte[RequestInitialFrameSize], UnfragmentedMessage); EncodeInt(initialFrame.Content, TypeFieldOffset, RequestMessageType); EncodeInt(initialFrame.Content, PartitionIdFieldOffset, -1); EncodeInt(initialFrame.Content, RequestBatchFieldOffset, batch); clientMessage.Add(initialFrame); StringCodec.Encode(clientMessage, name); EntryListIntegerIntegerCodec.Encode(clientMessage, iterationPointers); DataCodec.Encode(clientMessage, projection); DataCodec.Encode(clientMessage, predicate); return(clientMessage); }
public static ClientMessage EncodeRequest(string name, IData key, long threadId, long ttl, long referenceId) { var clientMessage = CreateForEncode(); clientMessage.IsRetryable = true; clientMessage.OperationName = "MultiMap.Lock"; var initialFrame = new Frame(new byte[RequestInitialFrameSize], UnfragmentedMessage); EncodeInt(initialFrame.Content, TypeFieldOffset, RequestMessageType); EncodeInt(initialFrame.Content, PartitionIdFieldOffset, -1); EncodeLong(initialFrame.Content, RequestThreadIdFieldOffset, threadId); EncodeLong(initialFrame.Content, RequestTtlFieldOffset, ttl); EncodeLong(initialFrame.Content, RequestReferenceIdFieldOffset, referenceId); clientMessage.Add(initialFrame); StringCodec.Encode(clientMessage, name); DataCodec.Encode(clientMessage, key); return(clientMessage); }
public static ClientMessage EncodeRequest(string name, IData key, long threadId, long referenceId) { var clientMessage = new ClientMessage { IsRetryable = true, OperationName = "MultiMap.Unlock" }; var initialFrame = new Frame(new byte[RequestInitialFrameSize], (FrameFlags)ClientMessageFlags.Unfragmented); initialFrame.Bytes.WriteIntL(Messaging.FrameFields.Offset.MessageType, RequestMessageType); initialFrame.Bytes.WriteIntL(Messaging.FrameFields.Offset.PartitionId, -1); initialFrame.Bytes.WriteLongL(RequestThreadIdFieldOffset, threadId); initialFrame.Bytes.WriteLongL(RequestReferenceIdFieldOffset, referenceId); clientMessage.Append(initialFrame); StringCodec.Encode(clientMessage, name); DataCodec.Encode(clientMessage, key); return(clientMessage); }
public static ClientMessage EncodeRequest(string name, ICollection <KeyValuePair <int, int> > iterationPointers, int batch, IData projection, IData predicate) { var clientMessage = new ClientMessage { IsRetryable = true, OperationName = "Map.FetchWithQuery" }; var initialFrame = new Frame(new byte[RequestInitialFrameSize], (FrameFlags)ClientMessageFlags.Unfragmented); initialFrame.Bytes.WriteIntL(Messaging.FrameFields.Offset.MessageType, RequestMessageType); initialFrame.Bytes.WriteIntL(Messaging.FrameFields.Offset.PartitionId, -1); initialFrame.Bytes.WriteIntL(RequestBatchFieldOffset, batch); clientMessage.Append(initialFrame); StringCodec.Encode(clientMessage, name); EntryListIntegerIntegerCodec.Encode(clientMessage, iterationPointers); DataCodec.Encode(clientMessage, projection); DataCodec.Encode(clientMessage, predicate); return(clientMessage); }
/// <summary> /// Set the palette data from an external palette file. /// </summary> /// <param name="palette">A VpPalette object</param> public void SetPalette(PvpPalette palette) { // No need to set an external palette if this data format doesn't require one. // We can't just call the data codec here as the data format does not determine // if a GVR uses an external palette. if (!NeedsExternalPalette) { return; } // If the palette is not initalized, don't use it if (!palette.Initalized) { return; } DataCodec.PixelCodec = palette.PixelCodec; DataCodec.SetPalette(palette.EncodedData, 0x10, palette.PaletteEntries); }
/// <summary> /// 通知所有用户房间列表有更新,发送新的房间列表 /// </summary> internal void OnRoomListUpdate() { RoomList list = new RoomList(); for (int i = 0; i < socketServerManager.GetRoomList().Count; i++) { string str = socketServerManager.GetRoomList()[i].RoomName + "," + socketServerManager.GetRoomList()[i].UserList.Count; list.List.Add(str); } DataModel model = new DataModel(); model.Type = DataType.TYPE_SPORDER; model.Request = DataRequest.GET_ROOMLIST_S; model.Message = DataCodec.TobyteArray(list); for (int i = 0; i < socketServerManager.GetClientList().Count; i++) { Send(socketServerManager.GetClientList()[i], model); } }
public static void Encode(ClientMessage clientMessage, Hazelcast.Data.HDictionaryEntry <IData, IData> simpleEntryView) { clientMessage.Append(Frame.CreateBeginStruct()); var initialFrame = new Frame(new byte[InitialFrameSize]); initialFrame.Bytes.WriteLongL(CostFieldOffset, simpleEntryView.Cost); initialFrame.Bytes.WriteLongL(CreationTimeFieldOffset, simpleEntryView.CreationTime); initialFrame.Bytes.WriteLongL(ExpirationTimeFieldOffset, simpleEntryView.ExpirationTime); initialFrame.Bytes.WriteLongL(HitsFieldOffset, simpleEntryView.Hits); initialFrame.Bytes.WriteLongL(LastAccessTimeFieldOffset, simpleEntryView.LastAccessTime); initialFrame.Bytes.WriteLongL(LastStoredTimeFieldOffset, simpleEntryView.LastStoredTime); initialFrame.Bytes.WriteLongL(LastUpdateTimeFieldOffset, simpleEntryView.LastUpdateTime); initialFrame.Bytes.WriteLongL(VersionFieldOffset, simpleEntryView.Version); initialFrame.Bytes.WriteLongL(TtlFieldOffset, simpleEntryView.Ttl); initialFrame.Bytes.WriteLongL(MaxIdleFieldOffset, simpleEntryView.MaxIdle); clientMessage.Append(initialFrame); DataCodec.Encode(clientMessage, simpleEntryView.Key); DataCodec.Encode(clientMessage, simpleEntryView.Value); clientMessage.Append(Frame.CreateEndStruct()); }
void HandlerData(byte[] data) { DataModel model = DataCodec.Decode(data); switch (model.Type) { case ChatProtocolType.TYPE_NONE: print("NONE:" + Encoding.UTF8.GetString(model.Message)); break; case ChatProtocolType.TYPE_MYSQL: mySqlHandler.MessageReceive(model); break; case ChatProtocolType.TYPE_IM: imHandler.MessageReceive(model); break; case ChatProtocolType.TYPE_MESSAGE: messageHandler.MessageReceive(model); break; } }
public static Hazelcast.Data.HDictionaryEntry <IData, IData> Decode(IEnumerator <Frame> iterator) { // begin frame iterator.Take(); var initialFrame = iterator.Take(); var cost = initialFrame.Bytes.ReadLongL(CostFieldOffset); var creationTime = initialFrame.Bytes.ReadLongL(CreationTimeFieldOffset); var expirationTime = initialFrame.Bytes.ReadLongL(ExpirationTimeFieldOffset); var hits = initialFrame.Bytes.ReadLongL(HitsFieldOffset); var lastAccessTime = initialFrame.Bytes.ReadLongL(LastAccessTimeFieldOffset); var lastStoredTime = initialFrame.Bytes.ReadLongL(LastStoredTimeFieldOffset); var lastUpdateTime = initialFrame.Bytes.ReadLongL(LastUpdateTimeFieldOffset); var version = initialFrame.Bytes.ReadLongL(VersionFieldOffset); var ttl = initialFrame.Bytes.ReadLongL(TtlFieldOffset); var maxIdle = initialFrame.Bytes.ReadLongL(MaxIdleFieldOffset); var key = DataCodec.Decode(iterator); var @value = DataCodec.Decode(iterator); iterator.SkipToStructEnd(); return(CustomTypeFactory.CreateSimpleEntryView(key, @value, cost, creationTime, expirationTime, hits, lastAccessTime, lastStoredTime, lastUpdateTime, version, ttl, maxIdle)); }
public static void Encode(ClientMessage clientMessage, Hazelcast.Map.SimpleEntryView <IData, IData> simpleEntryView) { clientMessage.Add(BeginFrame.Copy()); var initialFrame = new Frame(new byte[InitialFrameSize]); EncodeLong(initialFrame.Content, CostFieldOffset, simpleEntryView.Cost); EncodeLong(initialFrame.Content, CreationTimeFieldOffset, simpleEntryView.CreationTime); EncodeLong(initialFrame.Content, ExpirationTimeFieldOffset, simpleEntryView.ExpirationTime); EncodeLong(initialFrame.Content, HitsFieldOffset, simpleEntryView.Hits); EncodeLong(initialFrame.Content, LastAccessTimeFieldOffset, simpleEntryView.LastAccessTime); EncodeLong(initialFrame.Content, LastStoredTimeFieldOffset, simpleEntryView.LastStoredTime); EncodeLong(initialFrame.Content, LastUpdateTimeFieldOffset, simpleEntryView.LastUpdateTime); EncodeLong(initialFrame.Content, VersionFieldOffset, simpleEntryView.Version); EncodeLong(initialFrame.Content, TtlFieldOffset, simpleEntryView.Ttl); EncodeLong(initialFrame.Content, MaxIdleFieldOffset, simpleEntryView.MaxIdle); clientMessage.Add(initialFrame); DataCodec.Encode(clientMessage, simpleEntryView.Key); DataCodec.Encode(clientMessage, simpleEntryView.Value); clientMessage.Add(EndFrame.Copy()); }
public static Hazelcast.Map.SimpleEntryView <IData, IData> Decode(FrameIterator iterator) { // begin frame iterator.Next(); var initialFrame = iterator.Next(); var cost = DecodeLong(initialFrame.Content, CostFieldOffset); var creationTime = DecodeLong(initialFrame.Content, CreationTimeFieldOffset); var expirationTime = DecodeLong(initialFrame.Content, ExpirationTimeFieldOffset); var hits = DecodeLong(initialFrame.Content, HitsFieldOffset); var lastAccessTime = DecodeLong(initialFrame.Content, LastAccessTimeFieldOffset); var lastStoredTime = DecodeLong(initialFrame.Content, LastStoredTimeFieldOffset); var lastUpdateTime = DecodeLong(initialFrame.Content, LastUpdateTimeFieldOffset); var version = DecodeLong(initialFrame.Content, VersionFieldOffset); var ttl = DecodeLong(initialFrame.Content, TtlFieldOffset); var maxIdle = DecodeLong(initialFrame.Content, MaxIdleFieldOffset); var key = DataCodec.Decode(iterator); var @value = DataCodec.Decode(iterator); CodecUtil.FastForwardToEndFrame(iterator); return(CustomTypeFactory.CreateSimpleEntryView(key, @value, cost, creationTime, expirationTime, hits, lastAccessTime, lastStoredTime, lastUpdateTime, version, ttl, maxIdle)); }
public MemoryStream EncodeTexture() { // Calculate what the length of the texture will be int textureLength = 16 + (TextureWidth * TextureHeight * DataCodec.Bpp / 8); if (HasGlobalIndex) { textureLength += 16; } if (DataCodec.PaletteEntries != 0 && !DataCodec.NeedsExternalPalette) { textureLength += (DataCodec.PaletteEntries * PixelCodec.Bpp / 8); } // Calculate the mipmap padding (if the texture contains mipmaps) int mipmapPadding = 0; if (DataCodec.HasMipmaps) { if (DataFormat == PvrDataFormat.SQUARE_TWIDDLED_MIPMAP) { // A 1x1 mipmap takes up as much space as a 2x1 mipmap // There are also 4 extra bytes at the end of the file mipmapPadding = (DataCodec.Bpp) >> 3; textureLength += 4; } else if (DataFormat == PvrDataFormat.SQUARE_TWIDDLED_MIPMAP_ALT) { // A 1x1 mipmap takes up as much space as a 2x2 mipmap mipmapPadding = (3 * DataCodec.Bpp) >> 3; } textureLength += mipmapPadding; for (int size = 1; size < TextureWidth; size <<= 1) { textureLength += Math.Max((size * size * DataCodec.Bpp) >> 3, 1); } } MemoryStream destination = new MemoryStream(textureLength); // Write out the GBIX header (if we are including one) if (HasGlobalIndex) { destination.WriteByte((byte)'G'); destination.WriteByte((byte)'B'); destination.WriteByte((byte)'I'); destination.WriteByte((byte)'X'); PTStream.WriteUInt32(destination, 8); PTStream.WriteUInt32(destination, GlobalIndex); PTStream.WriteUInt32(destination, 0); } // Write out the PVRT header destination.WriteByte((byte)'P'); destination.WriteByte((byte)'V'); destination.WriteByte((byte)'R'); destination.WriteByte((byte)'T'); if (HasGlobalIndex) { PTStream.WriteInt32(destination, textureLength - 24); } else { PTStream.WriteInt32(destination, textureLength - 8); } destination.WriteByte((byte)PixelFormat); destination.WriteByte((byte)DataFormat); PTStream.WriteUInt16(destination, 0); PTStream.WriteUInt16(destination, TextureWidth); PTStream.WriteUInt16(destination, TextureHeight); // If we have an internal palette, write it if (DataCodec.PaletteEntries != 0 && !DataCodec.NeedsExternalPalette) { byte[] palette = PixelCodec.EncodePalette(m_texturePalette, DataCodec.PaletteEntries); destination.Write(palette, 0, palette.Length); } // Write out any mipmaps if (DataCodec.HasMipmaps) { // Write out any padding bytes before the 1x1 mipmap for (int i = 0; i < mipmapPadding; i++) { destination.WriteByte(0); } for (int size = 1; size < TextureWidth; size <<= 1) { byte[] mipmapDecodedData = null; if (DataCodec.NeedsExternalPalette) { if (DataCodec.VQ) { mipmapDecodedData = BitmapToRawVQResized(m_decodedBitmap, size, 1, m_codeBook); } else { mipmapDecodedData = BitmapToRawIndexedResized(m_decodedBitmap, size, 1, m_palette); } } else { mipmapDecodedData = BitmapToRawResized(m_decodedBitmap, size, 1); } byte[] mipmapTextureData = DataCodec.Encode(mipmapDecodedData, 0, size, size); destination.Write(mipmapTextureData, 0, mipmapTextureData.Length); } } // Write the texture data byte[] textureData = DataCodec.Encode(m_decodedData, TextureWidth, TextureHeight, null); destination.Write(textureData, 0, textureData.Length); // If the data format is square twiddled with mipmaps, write out the extra bytes. if (DataFormat == PvrDataFormat.SQUARE_TWIDDLED_MIPMAP) { destination.Write(new byte[] { 0, 0, 0, 0 }, 0, 4); } // Compress the texture if (CompressionFormat != PvrCompressionFormat.NONE) { CompressionCodec = PvrCompressionCodec.GetCompressionCodec(CompressionFormat); if (CompressionCodec != null) { // Ok, we need to convert the current stream to an array, compress it, then write it back to a new stream byte[] buffer = destination.ToArray(); buffer = CompressionCodec.Compress(buffer, (HasGlobalIndex ? 0x20 : 0x10), PixelCodec, DataCodec); destination = new MemoryStream(); destination.Write(buffer, 0, buffer.Length); } } return(destination); }
/// <summary> /// Internal read implementation of the sub classes. /// </summary> /// <param name="reader"></param> /// <exception cref="Exception">Expected DDS RGB24 or RGBA32 color format!</exception> /// <exception cref="NotImplementedException">TODO</exception> protected override void _Read(BinaryReader reader) { long baseOffset = reader.BaseStream.Position; int gbixOffset = 0; int pvrtOffset = 0; uint identifier = reader.ReadUInt32(); if (identifier == m_gbix) //"GBIX" { HasGlobalIndex = true; GlobalIndexSize = reader.ReadUInt32(); GlobalIndex = reader.ReadBytes((int)GlobalIndexSize); reader.BaseStream.Seek(4, SeekOrigin.Current); //Skip "PVRT" gbixOffset = 0x00; pvrtOffset = 0x08 + (int)GlobalIndexSize; } else { identifier = reader.ReadUInt32(); if (identifier == m_gbix) { HasGlobalIndex = true; GlobalIndexSize = reader.ReadUInt32(); GlobalIndex = reader.ReadBytes((int)GlobalIndexSize); gbixOffset = 0x04; pvrtOffset = 0x0C + (int)GlobalIndexSize; } else if (identifier == m_pvrt) { gbixOffset = -1; pvrtOffset = 0x04; } else { gbixOffset = -1; pvrtOffset = 0x00; reader.BaseStream.Seek(-4, SeekOrigin.Current); } } // Read information about the texture ContentSize = reader.ReadUInt32(); PixelFormat = (PvrPixelFormat)reader.ReadByte(); DataFormat = (PvrDataFormat)reader.ReadByte(); reader.BaseStream.Seek(2, SeekOrigin.Current); Width = reader.ReadUInt16(); Height = reader.ReadUInt16(); if (DataFormat == PvrDataFormat.DDS || DataFormat == PvrDataFormat.DDS_2) { if (!(PixelFormat == PvrPixelFormat.DDS_DXT1_RGB24 || PixelFormat == PvrPixelFormat.DDS_DXT3_RGBA32)) { throw new Exception("Expected DDS RGB24 or RGBA32 color format!"); } long ddsOffset = reader.BaseStream.Position; DDS_Header header = new DDS_Header(reader.BaseStream); DDSFormatDetails format = new DDSFormatDetails(header.Format, header.DX10_DXGI_AdditionalHeader.dxgiFormat); reader.BaseStream.Seek(ddsOffset, SeekOrigin.Begin); byte[] ddsBuffer = reader.ReadBytes(header.dwPitchOrLinearSize + header.dwSize + 128); MemoryStream memoryStream = new MemoryStream(ddsBuffer, 0, ddsBuffer.Length, true, true); MipMaps = DDSGeneral.LoadDDS(memoryStream, header, 0, format); memoryStream.Close(); Width = header.Width; Height = header.Height; } else { // 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 int paletteEntries = DataCodec.PaletteEntries; if (DataFormat == PvrDataFormat.VECTOR_QUANTIZATION_SMALL || DataFormat == PvrDataFormat.VECTOR_QUANTIZATION_SMALL_MIPMAP) { if (Width <= 16) { paletteEntries = 64; // Actually 16 } else if (Width <= 32) { paletteEntries = 256; // Actually 64 } else if (Width <= 64) { paletteEntries = 512; // Actually 128 } else { paletteEntries = 1024; // Actually 256 } } // Set the palette and data offsets int paletteOffset = 0; int dataOffset = 0; if (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 reader.BaseStream.Seek(baseOffset, SeekOrigin.Begin); uint first = reader.ReadUInt32(); reader.BaseStream.Seek(baseOffset + pvrtOffset + 4, SeekOrigin.Begin); uint second = reader.ReadUInt32(); if (first == second - pvrtOffset + dataOffset + 8) { CompressionFormat = PvrCompressionFormat.RLE; } else { CompressionFormat = PvrCompressionFormat.NONE; } CompressionCodec = PvrCompressionCodec.GetCompressionCodec(CompressionFormat); if (CompressionFormat != PvrCompressionFormat.NONE && CompressionCodec != null) { //TODO: Convert to stream compatible code throw new NotImplementedException("TODO"); //m_encodedData = CompressionCodec.Decompress(m_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 int[] mipmapOffsets; if (DataCodec.HasMipmaps) { int mipmapOffset = 0; mipmapOffsets = new int[(int)Math.Log(Width, 2) + 1]; // Calculate the padding for the first mipmap offset if (DataFormat == PvrDataFormat.SQUARE_TWIDDLED_MIPMAP) { mipmapOffset = (DataCodec.Bpp) >> 3; // A 1x1 mipmap takes up as much space as a 2x1 mipmap } else if (DataFormat == PvrDataFormat.SQUARE_TWIDDLED_MIPMAP_ALT) { mipmapOffset = (3 * DataCodec.Bpp) >> 3; // A 1x1 mipmap takes up as much space as a 2x2 mipmap } 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); } } else { mipmapOffsets = new int[1] { 0 }; } //DecodeMipmaps() if (paletteOffset != -1) // The texture contains an embedded palette { reader.BaseStream.Seek(baseOffset + paletteOffset, SeekOrigin.Begin); DataCodec.SetPalette(reader, paletteEntries); } MipMaps = new List <MipMap>(); if (DataCodec.HasMipmaps) { for (int i = 0, size = Width; i < mipmapOffsets.Length; i++, size >>= 1) { reader.BaseStream.Seek(baseOffset + dataOffset + mipmapOffsets[i], SeekOrigin.Begin); byte[] pixels = DataCodec.Decode(reader, size, size, PixelCodec); MipMaps.Add(new MipMap(pixels, size, size)); } } else { reader.BaseStream.Seek(baseOffset + dataOffset + mipmapOffsets[0], SeekOrigin.Begin); byte[] pixels = DataCodec.Decode(reader, Width, Height, PixelCodec); MipMaps.Add(new MipMap(pixels, Width, Height)); } } if (HasGlobalIndex) { reader.BaseStream.Seek(baseOffset + ContentSize + 0xC, SeekOrigin.Begin); } else { reader.BaseStream.Seek(baseOffset + ContentSize, SeekOrigin.Begin); } }
/// <summary> /// Internal write implementation of the sub classes. /// </summary> /// <param name="writer"></param> /// <exception cref="Exception">Expected DDS RGB24 or RGBA32 color format!</exception> /// <exception cref="InvalidOperationException"> /// </exception> protected override void _Write(BinaryWriter writer) { long baseOffset = writer.BaseStream.Position; Bitmap bmp = CreateBitmap(); //bmp.RotateFlip(RotateFlipType.RotateNoneFlipY); if (DataFormat == PvrDataFormat.DDS || DataFormat == PvrDataFormat.DDS_2) { if (!(PixelFormat == PvrPixelFormat.DDS_DXT1_RGB24 || PixelFormat == PvrPixelFormat.DDS_DXT3_RGBA32)) { throw new Exception("Expected DDS RGB24 or RGBA32 color format!"); } byte[] ddsBuffer = null; if (PixelFormat == PvrPixelFormat.DDS_DXT1_RGB24) { DDSFormatDetails ddsFormatDetails = new DDSFormatDetails(DDSFormat.DDS_DXT1); ddsBuffer = DDSGeneral.Save(MipMaps, ddsFormatDetails, DDSGeneral.AlphaSettings.KeepAlpha, DDSGeneral.MipHandling.Default); } else if (PixelFormat == PvrPixelFormat.DDS_DXT3_RGBA32) { DDSFormatDetails ddsFormatDetails = new DDSFormatDetails(DDSFormat.DDS_DXT3); ddsBuffer = DDSGeneral.Save(MipMaps, ddsFormatDetails, DDSGeneral.AlphaSettings.KeepAlpha, DDSGeneral.MipHandling.Default); } if (HasGlobalIndex) { writer.Write(m_gbix); writer.Write(GlobalIndexSize); writer.Write(GlobalIndex); } writer.Write(m_pvrt); writer.Write(ddsBuffer.Length + 16); writer.Write((byte)PixelFormat); writer.Write((byte)DataFormat); writer.Write((ushort)0); writer.Write((ushort)Width); writer.Write((ushort)Height); writer.Write(ddsBuffer); } else { // Set the data format and pixel format and load the appropiate codecs PixelCodec = PvrPixelCodec.GetPixelCodec(PixelFormat); DataCodec = PvrDataCodec.GetDataCodec(DataFormat); // Make sure the pixel and data codecs exists and we can encode to it if (PixelCodec == null || !PixelCodec.CanEncode) { throw new InvalidOperationException(); } if (DataCodec == null || !DataCodec.CanEncode) { throw new InvalidOperationException(); } DataCodec.PixelCodec = PixelCodec; byte[] decodedData = null; if (DataCodec.PaletteEntries != 0) { if (DataCodec.VQ) { decodedData = BitmapToRawVQ(bmp, DataCodec.PaletteEntries, out m_texturePalette); } else { // Convert the bitmap to an array containing indicies. decodedData = BitmapToRawIndexed(bmp, 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 { decodedData = BitmapToRaw(bmp); } // Calculate what the length of the texture will be int textureLength = 16 + (int)(Width * Height * (DataCodec.Bpp / 8.0)); if (HasGlobalIndex) { textureLength += 16; } if (DataCodec.PaletteEntries != 0 && !DataCodec.NeedsExternalPalette) { textureLength += (DataCodec.PaletteEntries * PixelCodec.Bpp / 8); } // Calculate the mipmap padding (if the texture contains mipmaps) int mipmapPadding = 0; if (DataCodec.HasMipmaps) { if (DataFormat == PvrDataFormat.SQUARE_TWIDDLED_MIPMAP) { // A 1x1 mipmap takes up as much space as a 2x1 mipmap // There are also 4 extra bytes at the end of the file mipmapPadding = (DataCodec.Bpp) >> 3; textureLength += 4; } else if (DataFormat == PvrDataFormat.SQUARE_TWIDDLED_MIPMAP_ALT) { // A 1x1 mipmap takes up as much space as a 2x2 mipmap mipmapPadding = (3 * DataCodec.Bpp) >> 3; } textureLength += mipmapPadding; for (int size = 1; size < Width; size <<= 1) { textureLength += Math.Max((size * size * DataCodec.Bpp) >> 3, 1); } } MemoryStream output = new MemoryStream(textureLength); BinaryWriter outputWriter = new BinaryWriter(output); // Write out the GBIX header (if we are including one) if (HasGlobalIndex) { outputWriter.Write(m_gbix); outputWriter.Write(GlobalIndexSize); outputWriter.Write(GlobalIndex); } // Write out the PVRT header outputWriter.Write(m_pvrt); if (HasGlobalIndex) { outputWriter.Write(textureLength - 24); } else { outputWriter.Write(textureLength - 8); } outputWriter.Write((byte)PixelFormat); outputWriter.Write((byte)DataFormat); outputWriter.Write((ushort)0); outputWriter.Write((ushort)Width); outputWriter.Write((ushort)Height); // If we have an internal palette, write it if (DataCodec.PaletteEntries != 0 && !DataCodec.NeedsExternalPalette) { byte[] palette = PixelCodec.EncodePalette(m_texturePalette, DataCodec.PaletteEntries); output.Write(palette, 0, palette.Length); } // Write out any mipmaps if (DataCodec.HasMipmaps) { // Write out any padding bytes before the 1x1 mipmap for (int i = 0; i < mipmapPadding; i++) { output.WriteByte(0); } for (int size = 1; size < Width; size <<= 1) { byte[] mipmapDecodedData = null; if (DataCodec.NeedsExternalPalette) { if (DataCodec.VQ) { mipmapDecodedData = BitmapToRawVQResized(bmp, size, 1, m_codeBook); } else { mipmapDecodedData = BitmapToRawIndexedResized(bmp, size, 1, m_palette); } } else { mipmapDecodedData = BitmapToRawResized(bmp, size, 1); } byte[] mipmapTextureData = DataCodec.Encode(mipmapDecodedData, 0, size, size); output.Write(mipmapTextureData, 0, mipmapTextureData.Length); } } // Write the texture data byte[] textureData = DataCodec.Encode(decodedData, Width, Height, null); output.Write(textureData, 0, textureData.Length); // If the data format is square twiddled with mipmaps, write out the extra bytes. if (DataFormat == PvrDataFormat.SQUARE_TWIDDLED_MIPMAP) { output.Write(new byte[] { 0, 0, 0, 0 }, 0, 4); } // Compress the texture if (CompressionFormat != PvrCompressionFormat.NONE) { CompressionCodec = PvrCompressionCodec.GetCompressionCodec(CompressionFormat); if (CompressionCodec != null) { // Ok, we need to convert the current stream to an array, compress it, then write it back to a new stream byte[] buffer = output.ToArray(); buffer = CompressionCodec.Compress(buffer, (HasGlobalIndex ? 0x20 : 0x10), PixelCodec, DataCodec); writer.Write(buffer); } } else { writer.Write(output.GetBuffer()); } } }