private CompressionType xBoxUncompress(string compFilename, string uncompFilename) { if (uncompFilename.ToLower() == compFilename.ToLower()) //nothing to do return CompressionType.None; if (File.Exists(uncompFilename)) File.Delete(uncompFilename); CompressionType ct = CompressionType.None; try { using (FileStream inFileStream = new FileStream(compFilename, FileMode.Open, FileAccess.Read)) { using (BinaryEndianReader br = new BinaryEndianReader(inFileStream)) { uint chunkLen = 0; while (chunkLen != 0xffffffff) { using (FileStream outFileStream = new FileStream(uncompFilename, chunkLen == 0 ? FileMode.Create : FileMode.Append)) { using (ZlibOutputStream outZStream = new ZlibOutputStream(outFileStream, Rebex.IO.Compression.CompressionMode.Decompress)) { //test for newer GHWT+ compression long pos = inFileStream.Position; if (Encoding.ASCII.GetString(br.ReadBytes(4)) == "CHNK") { ct = CompressionType.ZLibChunk; EndianType et = this.EndianType; //Decompress each section uint headerLen = br.ReadUInt32(et); uint blockLen = br.ReadUInt32(et); chunkLen = br.ReadUInt32(et); uint nextchunkLen = br.ReadUInt32(et); uint uncompressedLen = br.ReadUInt32(et); uint uncompressedPos = br.ReadUInt32(et); _zLibHeaderLen = headerLen; if (uncompressedLen > this._zLibChunkSize) this._zLibChunkSize = uncompressedLen; inFileStream.Seek(headerLen - (inFileStream.Position - pos), SeekOrigin.Current); outZStream.WriteByte(0x58); //Search deflate.cs for "Nanook" for the mod to stop it being written out outZStream.WriteByte(0x85); //this is the header MS uses, thie zlib deflate uses 78DA ?? copyStream(inFileStream, outZStream, (int)blockLen); if (chunkLen != 0xffffffff) inFileStream.Seek((chunkLen - blockLen) - headerLen, SeekOrigin.Current); } else { try { inFileStream.Seek(pos, SeekOrigin.Begin); outZStream.WriteByte(0x58); outZStream.WriteByte(0x85); copyStream(inFileStream, outZStream); ct = CompressionType.ZLib; break; } catch { break; //no compression??? } } outZStream.Flush(); outFileStream.Flush(); //outZStream.Close(); } } } } } } catch (Exception ex) { throw new ApplicationException(string.Format("Uncompress Failed: {0}", ex)); } //using (DeflateStream ds = new DeflateStream(File.Open(compFilename, FileMode.Open), CompressionMode.Decompress)) //{ // using (BinaryReader br = new BinaryReader(ds)) // { // using (FileStream ms = File.Create(uncompFilename)) // { // using (BinaryWriter bw = new BinaryWriter(ms)) // { // long l; // do // { // l = ms.Length; // bw.Write(br.ReadBytes(10000)); // } // while (l != ms.Length); // } // } // } //} return ct; }
private void xBoxCompress(string uncompFilename, string compFilename) { if (uncompFilename.ToLower() == compFilename.ToLower()) //nothing to do return; if (File.Exists(compFilename)) File.Delete(compFilename); try { if (this.CompressionType == CompressionType.ZLib) { using (FileStream outFileStream = new FileStream(compFilename, FileMode.Create)) { using (ZlibOutputStream outZStream = new ZlibOutputStream(outFileStream, true, JZlib.Z_BEST_COMPRESSION)) { using (FileStream inFileStream = new FileStream(uncompFilename, FileMode.Open, FileAccess.Read)) { copyStream(inFileStream, outZStream); } } } } else if (this.CompressionType == CompressionType.ZLibChunk) { List<uint> sizes = new List<uint>(); List<uint> offsets = new List<uint>(); byte[] header = new byte[ZlibFilePad]; int pad = 0; long lastUncompressedChunk; long endPos; EndianType et = this.EndianType; int part = 0; using (FileStream inFileStream = new FileStream(uncompFilename, FileMode.Open, FileAccess.Read)) { long pos; do { using (FileStream outFileStream = new FileStream(compFilename, inFileStream.Position == 0 ? FileMode.Create : FileMode.Append)) { part++; pad = (int)(outFileStream.Position % ZlibBlockPad); if (pad != 0 && outFileStream.Position != 0) outFileStream.Write(header, 0, (int)ZlibBlockPad - pad); pos = outFileStream.Position; outFileStream.Write(Encoding.ASCII.GetBytes("CHNK"), 0, 4); outFileStream.Write(header, 0, (int)_zLibHeaderLen - 4); lastUncompressedChunk = (long)_zLibChunkSize; if (inFileStream.Position + lastUncompressedChunk > inFileStream.Length) lastUncompressedChunk = inFileStream.Length - inFileStream.Position; using (ZlibOutputStream outZStream = new ZlibOutputStream(outFileStream, true, JZlib.Z_BEST_COMPRESSION)) { copyStream(inFileStream, outZStream, (int)lastUncompressedChunk); offsets.Add((uint)pos); sizes.Add((uint)(outFileStream.Position - pos) - _zLibHeaderLen); } } } while (inFileStream.Position < inFileStream.Length); using (FileStream outFileStream = new FileStream(compFilename, inFileStream.Position == 0 ? FileMode.Create : FileMode.Append)) { //find the end of the last file. endPos = (int)(outFileStream.Position % ZlibBlockPad); if (endPos != 0) endPos = ZlibBlockPad - endPos; endPos += outFileStream.Position; //pad the compressed file pad = (int)(outFileStream.Position % ZlibFilePad); if (pad != 0 && outFileStream.Position != 0) outFileStream.Write(header, 0, (int)ZlibFilePad - pad); } using (FileStream outFileStream = new FileStream(compFilename, FileMode.Open)) { using (BinaryEndianWriter bw = new BinaryEndianWriter(outFileStream)) { long uncompressedTotal = 0; EndianType e = this.EndianType; for (int i = 0; i < offsets.Count; i++) { outFileStream.Seek(offsets[i] + 4, SeekOrigin.Begin); bw.Write((uint)_zLibHeaderLen, e); //headerlen bw.Write((uint)sizes[i], e); //blocklen bw.Write((uint)(i != offsets.Count - 1 ? offsets[i + 1] - offsets[i] : 0xffffffff), e); //chunklen ffs if last item //next blocklen 00's if last block if (i == offsets.Count - 1) //last item bw.Write((uint)0x00000000, e); else if (i + 1 == offsets.Count - 1) //secondlast item bw.Write((uint)(endPos - offsets[i + 1]), e); else bw.Write((uint)offsets[i + 2] - offsets[i + 1], e); bw.Write((uint)(i != offsets.Count - 1 ? _zLibChunkSize : lastUncompressedChunk), e); //uncompressed size bw.Write((uint)uncompressedTotal, e); uncompressedTotal += (i != offsets.Count - 1 ? _zLibChunkSize : lastUncompressedChunk); } } } } } } catch (Exception ex) { throw new ApplicationException(string.Format("Compress Failed: {0}", ex)); } //using (FileStream sf = File.OpenRead(uncompFilename)) //{ // using (FileStream df = File.Create(compFilename)) // { // using (DeflateStream ds = new DeflateStream(df, CompressionMode.Compress)) // { // byte[] b = new byte[10000]; // int c = 0; // do // { // c = sf.Read(b, 0, b.Length); // ds.Write(b, 0, c); // } // while (c == b.Length); // } // } //} }