public static void importTexture(GpkExport export, string file) { var texture2d = export.Payload as Texture2D; var image = new DdsFile(); var config = new DdsSaveConfig(texture2d.GetFormat(), 0, 0, false, false); image.Load(file); if (image.MipMaps.Count == 0 || Settings.Default.GenerateMipMaps) { image.GenerateMipMaps(); } texture2d.maps = new List <MipMap>(); foreach (DdsMipMap mipMap in image.MipMaps.OrderByDescending(mip => mip.Width)) { byte[] outputData = image.WriteMipMap(mipMap, config); var textureMipMap = new MipMap(); textureMipMap.compFlag = (int)CompressionTypes.LZO; textureMipMap.uncompressedData = outputData; textureMipMap.uncompressedSize = outputData.Length; textureMipMap.uncompressedSize_chunkheader = outputData.Length; textureMipMap.sizeX = mipMap.Width; textureMipMap.sizeY = mipMap.Height; textureMipMap.generateBlocks(); texture2d.maps.Add(textureMipMap); } }
public void ReadData(GpkPackage package, GpkExport export) { BinaryReader reader = new BinaryReader(new MemoryStream(export.Data)); ObjectIndex = reader.ReadInt32(); ObjectName = package.GetObjectName(ObjectIndex); }
public static void ParsePayload(GpkPackage package, GpkExport export) { switch (export.ClassName) { case "Core.SoundNodeWave": export.Payload = new Soundwave(); break; case "Core.SoundCue": export.Payload = new SoundCue(); break; case "Core.Texture2D": if (Settings.Default.EnableTexture2D) { //gmp hack if (isStrangeCompressedTexture(export)) { break; } export.Payload = new Texture2D(); } break; } if (export.Payload != null) { export.Payload.ReadData(package, export); } }
public static void exportTexture(GpkExport export, string file) { Texture2D image = (Texture2D)export.Payload; DdsFile ddsFile = new DdsFile(); Task.Run(() => image.SaveObject(file, new DdsSaveConfig(image.GetFormat(), 0, 0, false, false))); }
public static string GenerateUID(GpkPackage package, GpkExport export) { string proposedName; if (export.PackageName == "none") { proposedName = export.ObjectName; } else { proposedName = export.PackageName + "." + export.ObjectName; } int counter = 0; do { string tmpName = proposedName; if (counter > 0) { tmpName += ("_" + counter); } if (package.UidList.ContainsKey(tmpName) == false) { package.UidList.Add(tmpName, ""); return(tmpName); } counter++; } while (true); }
public static void ExportOgg(GpkExport export, string oggfile) { if (export.Payload == null) { logger.Info("No data. The file cannot be exported to ogg."); return; } if (!(export.Payload is Soundwave)) { logger.Info("Wrong payload data. The file cannot be exported to ogg."); return; } Soundwave wave = (Soundwave)export.Payload; if (wave.oggdata == null) { logger.Info("Empty Oggdata. The file cannot be exported to ogg."); return; } StreamWriter writer = new StreamWriter(File.OpenWrite(oggfile)); writer.BaseStream.Write(wave.oggdata, 0, wave.oggdata.Length); writer.Close(); writer.Dispose(); logger.Info(String.Format("Data was saved to {0}!", Path.GetFileName(oggfile))); }
public static void ReplaceProperties(GpkExport source, GpkExport destination) { destination.Properties.Clear(); destination.Properties.AddRange(source.Properties.ToArray()); destination.PropertyPadding = source.PropertyPadding; destination.PropertySize = source.PropertySize; destination.PropertyPadding = source.PropertyPadding; }
public void WriteData(BinaryWriter writer, GpkPackage package, GpkExport export) { writer.Write(startUnk); if (inUnicode) { Writer.WriteUnicodeString(writer, tgaPath, true); } else { Writer.WriteString(writer, tgaPath, true); } writer.Write(maps.Count); foreach (var map in maps) { //refressh block info, compress blocks map.generateBlocks(); //chunk //info writer.Write(map.compFlag); writer.Write(map.uncompressedSize); int chunkSize = 16 + map.blocks.Count * 8 + map.compressedSize; if (chunkSize != map.compChunkSize) { logger.Info("fixing chunksize"); map.compChunkSize = chunkSize; } writer.Write(map.compChunkSize); writer.Write((int)(writer.BaseStream.Position + 4)); //chunkoffset //header writer.Write(map.signature); writer.Write(map.blocksize); writer.Write(map.compressedSize); writer.Write(map.uncompressedSize_chunkheader); foreach (var block in map.blocks) { writer.Write(block.compressedSize); writer.Write(block.uncompressedDataSize); } foreach (var block in map.blocks) { writer.Write(block.compressedData); } writer.Write(map.sizeX); writer.Write(map.sizeY); } writer.Write(guid); }
public void WriteData(BinaryWriter writer, GpkPackage package, GpkExport export) { writer.Write(cues.Count); foreach (SoundCueObject cue in cues) { writer.Write((int)package.GetObjectIndex(cue.objectName)); writer.Write(cue.Unk2); writer.Write(cue.Unk3); } }
public static Boolean isStrangeCompressedTexture(GpkExport export) { foreach (GpkBaseProperty prop in export.Properties) { if (prop.name == "CompressionNoMipmaps" || prop.name == "CompressionNoAlpha") { return(true); } } return(false); }
private void ReadExports(BinaryReader reader, GpkPackage package) { logger.Debug("Reading Exports at {0}....", package.Header.ExportOffset); reader.BaseStream.Seek(package.Header.ExportOffset, SeekOrigin.Begin); for (int i = 0; i < package.Header.ExportCount; i++) { GpkExport export = new GpkExport(package); export.ClassIndex = reader.ReadInt32(); export.SuperIndex = reader.ReadInt32(); export.PackageIndex = reader.ReadInt32(); long nameIndex = reader.ReadInt32(); export.ObjectName = package.GetString(nameIndex); export.Unk1 = reader.ReadInt64(); export.Unk2 = reader.ReadInt64(); export.SerialSize = reader.ReadInt32(); if (export.SerialSize > 0) { export.SerialOffset = reader.ReadInt32(); } export.Unk3 = reader.ReadInt32(); export.UnkHeaderCount = reader.ReadInt32(); export.Unk4 = reader.ReadInt32(); export.Guid = reader.ReadBytes(16); export.UnkExtraInts = reader.ReadBytes(export.UnkHeaderCount * 4); package.ExportList.Add(i, export); logger.Debug("Export {0}: ObjectName: {1}, Data_Size: {2}, Data_Offset {3}, Export_offset {4}", i, export.ObjectName, export.SerialSize, export.SerialOffset, reader.BaseStream.Position); stat.progress++; } //post-processing. needed if a object points to another export. logger.Debug("Linking Exports.."); foreach (KeyValuePair <long, GpkExport> pair in package.ExportList) { GpkExport export = pair.Value; if (export.ClassName == null || export.SuperName == null || export.PackageName == null || export.UID == null) { export.ClassName = package.GetObjectName(export.ClassIndex); export.SuperName = package.GetObjectName(export.SuperIndex); export.PackageName = package.GetObjectName(export.PackageIndex); export.UID = GenerateUID(package, export); } stat.progress++; } }
public void ReadData(GpkPackage package, GpkExport export) { BinaryReader reader = new BinaryReader(new MemoryStream(export.Data)); IProperty formatProp = export.Properties.Find(t => ((GpkBaseProperty)t).name == "Format"); String format = ((GpkByteProperty)formatProp).nameValue; reader.ReadBytes(16); int len = reader.ReadInt32() * -1 * 2; string name = Reader.ReadUnicodeString(reader, len); int mipMapSize = reader.ReadInt32(); }
public void ResetGUI() { selectedExport = null; selectedPackage = null; selectedClass = ""; boxInfo.Text = ""; boxGeneralButtons.Enabled = false; boxDataButtons.Enabled = false; boxPropertyButtons.Enabled = false; ProgressBar.Value = 0; lblStatus.Text = "Ready"; ClearGrid(); }
public void SaveFormat(GpkExport export) { GpkByteProperty formatProp = export.GetProperty("Format") as GpkByteProperty; if (formatProp == null) { parsedImageFormat = FileFormat.Unknown; } else { string format = formatProp.nameValue; parsedImageFormat = DdsPixelFormat.ParseFileFormat(format); } }
//http://forums.nexusmods.com/index.php?/topic/1964864-sound-replacement-possible/#entry18577584 public void ReadData(GpkPackage package, GpkExport export) { BinaryReader reader = new BinaryReader(new MemoryStream(export.Data)); reader.ReadBytes(20); //(12bytes 00) int ogg_length1 = reader.ReadInt32(); int ogg_length2 = reader.ReadInt32(); int offset1 = reader.ReadInt32(); oggdata = new byte[ogg_length1]; oggdata = reader.ReadBytes(ogg_length1); reader.ReadBytes(32); //2x(12bytes 00 + offset +4) }
public void ReadData(GpkPackage package, GpkExport export) { IProperty arrayProp = export.Properties.Find(t => ((GpkBaseProperty)t).name == "ReferencedObjects"); var data = ((GpkArrayProperty)arrayProp).value; BinaryReader reader = new BinaryReader(new MemoryStream(data)); count = reader.ReadInt32(); referencedObjects = new string[count]; for (int i = 0; i < count; i++) { int objIndex = reader.ReadInt32(); referencedObjects[i] = package.GetObjectName(objIndex); } }
public static void importTexture(GpkExport export, string file) { try { var texture2d = export.Payload as Texture2D; var image = new DdsFile(); var config = new DdsSaveConfig(texture2d.parsedImageFormat, 0, 0, false, false); image.Load(file); if (image.MipMaps.Count == 0 || CoreSettings.Default.GenerateMipMaps) { image.GenerateMipMaps(); } texture2d.maps = new List <MipMap>(); foreach (DdsMipMap mipMap in image.MipMaps.OrderByDescending(mip => mip.Width)) { byte[] outputData = image.WriteMipMap(mipMap, config); var textureMipMap = new MipMap(); textureMipMap.flags = (int)CompressionTypes.LZO; //textureMipMap.flags = 0; textureMipMap.uncompressedData = outputData; textureMipMap.uncompressedSize = outputData.Length; textureMipMap.uncompressedSize_chunkheader = outputData.Length; textureMipMap.sizeX = mipMap.Width; textureMipMap.sizeY = mipMap.Height; if (textureMipMap.flags != 0) { textureMipMap.generateBlocks(); } texture2d.maps.Add(textureMipMap); } int mipTailBaseIdx = (int)Math.Log(image.Width > image.Height ? image.Width : image.Height, 2); ((GpkIntProperty)export.GetProperty("MipTailBaseIdx")).SetValue(mipTailBaseIdx.ToString()); logger.Info("Imported image from {0}, size {1}x{2}, target format {3}, mipTailBaseIdx {4}", file, image.Width, image.Height, config.FileFormat, mipTailBaseIdx); } catch (Exception ex) { logger.Error(ex, "Failed to import texture"); logger.Error(ex); } }
public void ReadData(GpkPackage package, GpkExport export) { BinaryReader reader = new BinaryReader(new MemoryStream(export.Data)); int count = reader.ReadInt32(); for (int i = 0; i < count; i++) { SoundCueObject cue = new SoundCueObject(); cue.objectName = package.GetObjectName(reader.ReadInt32()); cue.Unk2 = reader.ReadInt32(); cue.Unk3 = reader.ReadInt32(); cues.Add(cue); } }
private void treeMain_AfterSelect(object sender, TreeViewEventArgs e) { ResetGUI(); if (e.Node.Level == 0) { boxGeneralButtons.Enabled = true; boxDataButtons.Enabled = true; selectedPackage = loadedGpkPackages[Convert.ToInt32(e.Node.Name)]; boxInfo.Text = selectedPackage.ToString(); } else if (e.Node.Level == 1 && Settings.Default.ViewMode == "class") { selectedPackage = loadedGpkPackages[Convert.ToInt32(e.Node.Parent.Name)]; selectedClass = e.Node.Text; boxDataButtons.Enabled = true; } else if (e.Node.Level == 2) { GpkPackage package = loadedGpkPackages[Convert.ToInt32(e.Node.Parent.Parent.Name)]; Object selected = package.GetObjectByUID(e.Node.Name); if (selected is GpkImport) { GpkImport imp = (GpkImport)selected; boxInfo.Text = imp.ToString(); } else if (selected is GpkExport) { GpkExport exp = (GpkExport)selected; boxInfo.Text = exp.ToString(); boxGeneralButtons.Enabled = true; boxDataButtons.Enabled = true; boxPropertyButtons.Enabled = true; selectedExport = exp; selectedPackage = package; DrawGrid(package, exp); } } }
private void btnPaste_Click(object sender, EventArgs e) { if (selectedExport == null) { logger.Trace("no selected export"); return; } GpkExport copyExport = (GpkExport)Clipboard.GetData(exportFormat.Name); if (copyExport == null) { logger.Info("copy paste fail"); return; } logger.Trace(Settings.Default.CopyMode); string option = ""; switch (Settings.Default.CopyMode) { case "dataprops": DataTools.ReplaceProperties(copyExport, selectedExport); DataTools.ReplaceData(copyExport, selectedExport); option = "data and properties"; break; case "data": DataTools.ReplaceData(copyExport, selectedExport); option = "data"; break; case "props": DataTools.ReplaceProperties(copyExport, selectedExport); option = "properties"; break; default: logger.Info("Your setting file is broken. Go to settings windows and select a copymode."); break; } copyExport.GetDataSize(); treeMain_AfterSelect(treeMain, new TreeViewEventArgs(treeMain.SelectedNode)); logger.Info("Pasted the {0} of {1} to {2}", option, copyExport.UID, selectedExport.UID); }
public void WriteData(BinaryWriter writer, GpkPackage package, GpkExport export) { /* * useless code atm, payload is written after props, so rewrite here does not make any sense * * GpkArrayProperty arrayProp = (GpkArrayProperty)export.Properties.Find(t => ((GpkBaseProperty)t).name == "ReferencedObjects"); * var data = new byte[count * 4 + 4]; * * BinaryWriter writerProp = new BinaryWriter(new MemoryStream(data)); * writerProp.Write(count); * for (int i = 0; i < count; i++) * { * writerProp.Write(Convert.ToInt32(package.GetObjectIndex(referencedObjects[i]))); * } * * arrayProp.value = data; * arrayProp.RecalculateSize(); */ }
public static void exportTexture(GpkExport export, string file) { try { Texture2D image = (Texture2D)export.Payload; DdsFile ddsFile = new DdsFile(); if (image == null || ddsFile == null) { return; } image.SaveObject(file, new DdsSaveConfig(image.parsedImageFormat, 0, 0, false, false)); } catch (Exception ex) { logger.Error(ex, "Failed to export texture"); logger.Error(ex); } }
public static void ParsePayload(GpkPackage package, GpkExport export) { switch (export.ClassName) { case "Core.SoundNodeWave": export.Payload = new Soundwave(); break; case "Core.SoundCue": export.Payload = new SoundCue(); break; case "Core.Texture2D": //export.Payload = new Texture2D(); break; } if (export.Payload != null) { export.Payload.ReadData(package, export); } }
public void WriteData(BinaryWriter writer, GpkPackage package, GpkExport export) { if (oggdata == null) { throw new Exception("Oggdata is null. Object: " + export.UID); } writer.Write(new byte[12]); writer.Write((int)writer.BaseStream.Position + 4); writer.Write(0); writer.Write(oggdata.Length); writer.Write(oggdata.Length); writer.Write((int)writer.BaseStream.Position + 4); writer.Write(oggdata); writer.Write(new byte[12]); writer.Write((int)writer.BaseStream.Position + 4); writer.Write(new byte[12]); writer.Write((int)writer.BaseStream.Position + 4); }
public static void ReplaceAll(GpkExport source, GpkExport destination) { GpkPackage sourcePackage = source.motherPackage; GpkPackage destinantionPackage = destination.motherPackage; //exclude: motherPackage, guid, uid, SerialOffset, SerialOffsetPosition, ObjectName, PackageName destination.ClassName = source.ClassName; destination.SuperName = source.SuperName; //destination.PackageName = source.PackageName; //destination.ObjectName = source.ObjectName; destination.Unk1 = source.Unk1; destination.Unk2 = source.Unk2; destination.SerialSize = source.SerialSize; destination.NetIndex = source.NetIndex; destination.NetIndexName = source.NetIndexName; destination.Unk3 = source.Unk3; destination.UnkHeaderCount = source.UnkHeaderCount; destination.Unk4 = source.Unk4; destination.UnkExtraInts = source.UnkExtraInts; destination.DependsTableData = source.DependsTableData; ReplaceProperties(source, destination); ReplaceData(source, destination); //regenerate uid destinantionPackage.GenerateUID(destination); //copy deps destinantionPackage.CopyObjectFromPackage(source.ClassName, sourcePackage, false); destinantionPackage.CopyObjectFromPackage(source.PackageName, sourcePackage, false); destinantionPackage.CopyObjectFromPackage(source.SuperName, sourcePackage, false); destinantionPackage.CopyObjectFromPackage(source.NetIndexName, sourcePackage, false); }
private void btnDelete_Click(object sender, EventArgs e) { if (selectedPackage != null && selectedExport == null) { loadedGpkPackages.Remove(selectedPackage); DrawPackages(); logger.Info("Removed package {0}...", selectedPackage.Filename); selectedPackage = null; boxGeneralButtons.Enabled = false; } else if (selectedPackage != null && selectedExport != null) { selectedPackage.ExportList.Remove(selectedPackage.GetObjectKeyByUID(selectedExport.UID)); logger.Info("Removed object {0}...", selectedExport.UID); selectedExport = null; treeMain.Nodes.Remove(treeMain.SelectedNode); } }
private void ReadExportData(BinaryReader reader, GpkPackage package) { logger.Debug("Reading ExportsData...."); long maxValue = 0; GpkExport maxExp = null; foreach (GpkExport export in package.ExportList.Values) { try { reader.BaseStream.Seek(export.SerialOffset, SeekOrigin.Begin); //int objectindex (netindex) export.NetIndex = reader.ReadInt32(); if (export.NetIndex != 0) { //export.netIndexName = package.GetObjectName(netIndex, true); } //dirty hack until we find the begin long namePosStart = reader.BaseStream.Position; while (true) { long test_nameindex = reader.ReadInt64(); if (package.NameList.ContainsKey(test_nameindex)) { long tmpNameStartPos = reader.BaseStream.Position - 8; long name_padding_count = tmpNameStartPos - namePosStart; reader.BaseStream.Seek(namePosStart, SeekOrigin.Begin); export.PropertyPadding = new byte[name_padding_count]; export.PropertyPadding = reader.ReadBytes((int)name_padding_count); //reader.BaseStream.Seek(name_start, SeekOrigin.Begin); break; } reader.BaseStream.Seek(reader.BaseStream.Position - 7, SeekOrigin.Begin); } //bad style :( //logger.Info("First {0} Skip {1}", first, reader.BaseStream.Position - export.SerialOffset); //Props bool cont = true; while (cont) { cont = ReadPropertyDetails(reader, package, export); } export.PropertySize = (int)reader.BaseStream.Position - export.SerialOffset; //data part long object_end = export.SerialOffset + export.SerialSize; int toread = 0; string tag = ""; if (reader.BaseStream.Position < object_end) { toread = (int)(object_end - reader.BaseStream.Position); export.DataStart = reader.BaseStream.Position; if (Settings.Default.JitData) { //use our dataloader, will be just loaded if needed. more performance, less memory cons. tag = "JIT"; export.Loader = new DataLoader(package.Path, (int)export.DataStart, toread); } else { //load everything aot tag = "AOT"; export.Data = new byte[toread]; export.Data = reader.ReadBytes(toread); ParsePayload(package, export); if (export.Payload != null) { logger.Debug(export.Payload.ToString()); } } } logger.Debug(String.Format("Export {0}: Read Data ({1} bytes {2}) and {3} Properties ({4} bytes)", export.ObjectName, toread, tag, export.Properties.Count, export.PropertySize)); long totalRead = reader.BaseStream.Position - export.SerialOffset; long shouldBe = export.SerialSize; long oursize = export.GetDataSize(); if (totalRead != shouldBe || totalRead != oursize) { logger.Debug(String.Format("totalRead {0} GetDataSize {1} shouldBe {2}", totalRead, oursize, shouldBe)); } if (reader.BaseStream.Position > maxValue) { maxValue = reader.BaseStream.Position; maxExp = export; } } catch (Exception ex) { logger.Fatal("[ReadExportData] UID: {0} Error: {1}", export.UID, ex); } //data stat.progress++; } logger.Debug("MAX VALUE " + maxValue); logger.Debug("MAX EXPORT " + maxExp.ObjectName); }
private Boolean ReadPropertyDetails(BinaryReader reader, GpkPackage package, GpkExport export) { GpkBaseProperty baseProp = new GpkBaseProperty(); long nameindex = reader.ReadInt64(); if (!package.NameList.ContainsKey(nameindex)) { logger.Fatal("name not found " + nameindex); if (export.Properties.Count > 0) { logger.Fatal("prev " + export.Properties[export.Properties.Count - 1]); } } baseProp.name = package.GetString(nameindex); if (baseProp.name.ToLower() == "none") { return(false); } long typeindex = reader.ReadInt64(); if (!package.NameList.ContainsKey(typeindex)) { logger.Fatal("type not found " + typeindex); } baseProp.type = package.GetString(typeindex); baseProp.size = reader.ReadInt32(); baseProp.arrayIndex = reader.ReadInt32(); IProperty iProp; switch (baseProp.type) { case "StructProperty": iProp = new GpkStructProperty(baseProp); break; case "ArrayProperty": iProp = new GpkArrayProperty(baseProp); break; case "BoolProperty": iProp = new GpkBoolProperty(baseProp); break; case "ByteProperty": iProp = new GpkByteProperty(baseProp); break; case "NameProperty": iProp = new GpkNameProperty(baseProp); break; case "IntProperty": iProp = new GpkIntProperty(baseProp); break; case "FloatProperty": iProp = new GpkFloatProperty(baseProp); break; case "StrProperty": iProp = new GpkStringProperty(baseProp); break; case "ObjectProperty": iProp = new GpkObjectProperty(baseProp); break; default: throw new Exception( string.Format( "Unknown Property Type {0}, Position {1}, Prop_Name {2}, Export_Name {3}", baseProp.type, reader.BaseStream.Position, baseProp.name, export.ObjectName)); } iProp.ReadData(reader, package); iProp.RecalculateSize(); export.Properties.Add(iProp); //logger.Trace(String.Format("Property Type {0}, Position after {1}, Prop_Name {2}, Export_Name {3}", baseProp.type, reader.BaseStream.Position, baseProp.ObjectName, export.ObjectName)); return(true); }
public void WriteData(BinaryWriter writer, GpkPackage package, GpkExport export) { writer.Write(startUnk); if (inUnicode) { Writer.WriteUnicodeString(writer, tgaPath, true); } else { Writer.WriteString(writer, tgaPath, true); } writer.Write(maps.Count); foreach (var map in maps) { //refressh block info, compress blocks //map.generateBlocks(); //chunk //info writer.Write(map.compFlag); writer.Write(map.uncompressedSize); if (((CompressionTypes)map.compFlag & NothingToDo) == 0) { int chunkSize = 16 + map.blocks.Count * 8 + map.compressedSize; if (chunkSize != map.compChunkSize) { logger.Info("fixing chunksize for " + objectExport.ObjectName); map.compChunkSize = chunkSize; } writer.Write(map.compChunkSize); writer.Write((int)(writer.BaseStream.Position + 4)); //chunkoffset //header writer.Write(map.signature); writer.Write(map.blocksize); writer.Write(map.compressedSize); writer.Write(map.uncompressedSize_chunkheader); foreach (var block in map.blocks) { writer.Write(block.compressedSize); writer.Write(block.uncompressedDataSize); } foreach (var block in map.blocks) { writer.Write(block.compressedData); } } else { writer.Write((int)-1); //chunksize writer.Write((int)-1); //chunkoffset logger.Trace("writing {0}, MipMap {0}, with no data!!", export.ObjectName, map); } writer.Write(map.sizeX); writer.Write(map.sizeY); } writer.Write(guid); }
public void ReadData(GpkPackage package, GpkExport export) { objectExport = export; BinaryReader reader = new BinaryReader(new MemoryStream(export.Data)); IProperty formatProp = export.Properties.Find(t => ((GpkBaseProperty)t).name == "Format"); String format = ((GpkByteProperty)formatProp).nameValue; startUnk = reader.ReadBytes(16); int length = reader.ReadInt32(); if (length > 0) { tgaPath = Reader.ReadString(reader, length); } else { inUnicode = true; tgaPath = Reader.ReadUnicodeString(reader, (length * -1) * 2); } int count = reader.ReadInt32(); for (int i = 0; i < count; i++) { MipMap map = new MipMap(); //chunk //info map.compFlag = reader.ReadInt32(); map.uncompressedSize = reader.ReadInt32(); map.compChunkSize = reader.ReadInt32(); map.compChunkOffset = reader.ReadInt32(); var temp = ((CompressionTypes)map.compFlag & NothingToDo); if (((CompressionTypes)map.compFlag & NothingToDo) == 0) { //header map.signature = reader.ReadUInt32(); //0x9e2a83c1 Debug.Assert(map.signature == MipMap.DEFAULT_SIGNATURE); map.blocksize = reader.ReadInt32(); map.compressedSize = reader.ReadInt32(); map.uncompressedSize_chunkheader = reader.ReadInt32(); map.uncompressedData = new byte[map.uncompressedSize]; int blockCount = (map.uncompressedSize + map.blocksize - 1) / map.blocksize; int blockOffset = 0; for (int j = 0; j < blockCount; ++j) { var block = new ChunkBlock(); block.compressedSize = reader.ReadInt32(); block.uncompressedDataSize = reader.ReadInt32(); map.blocks.Add(block); } foreach (ChunkBlock block in map.blocks) { block.compressedData = reader.ReadBytes(block.compressedSize); block.decompress(map.compFlag); Array.ConstrainedCopy(block.uncompressedData, 0, map.uncompressedData, blockOffset, block.uncompressedDataSize); blockOffset += block.uncompressedDataSize; //save memory block.uncompressedData = null; } } else { logger.Trace("{0}, MipMap {0}, no data!!", export.ObjectName, i); } map.sizeX = reader.ReadInt32(); map.sizeY = reader.ReadInt32(); maps.Add(map); } guid = reader.ReadBytes(16); }