Esempio n. 1
0
        protected override void WriteDataToStream(Stream stream, SharedExtractParams extractParams, bool decompress)
        {
            var  reader = extractParams.Reader;
            uint len    = this.Compressed ? this.Size : this.RealSize;

            reader.BaseStream.Seek((long)this.Offset, SeekOrigin.Begin);
            // Reset at start since value might still be in used for a bit after
            this.BytesWritten = 0;

            if (!decompress || !this.Compressed)
            {
                StreamUtils.WriteSectionToStream(reader.BaseStream,
                                                 len,
                                                 stream,
                                                 bytesWritten => this.BytesWritten = bytesWritten);
            }
            else
            {
                CompressionUtils.Decompress(reader.BaseStream,
                                            len,
                                            stream,
                                            bytesWritten => this.BytesWritten = bytesWritten,
                                            extractParams);
            }
        }
Esempio n. 2
0
        public override ulong GetSizeInArchive(SharedExtractParams extractParams)
        {
            if (this.Archive.Type == ArchiveTypes.BSA_SE)
            {
                var   reader = extractParams.Reader;
                ulong filesz = this.Size & 0x3fffffff;
                reader.BaseStream.Position = (long)Offset;

                if (this.Archive.ContainsFileNameBlobs)
                {
                    int len = reader.ReadByte();
                    filesz -= (ulong)len + 1;
                }

                if (this.Size > 0 && this.Compressed)
                {
                    filesz -= 4;
                }

                return(filesz);
            }
            else
            {
                return(this.Size);
            }
        }
Esempio n. 3
0
        private void WriteChunks(Stream stream, SharedExtractParams extractParams, bool decompress)
        {
            var reader = extractParams.Reader;

            for (int i = 0; i < (numChunks - 1); i++)
            {
                reader.BaseStream.Seek((long)this.Chunks[i].offset, SeekOrigin.Begin);


                if (!decompress)
                {
                    ulong prev = this.BytesWritten;
                    StreamUtils.WriteSectionToStream(reader.BaseStream,
                                                     Math.Max(Chunks[i].packSz, Chunks[i].fullSz), // Lazy hack, only one should be set when not compressed
                                                     stream,
                                                     bytesWritten => this.BytesWritten = prev + bytesWritten);
                }
                else
                {
                    ulong prev = this.BytesWritten;
                    CompressionUtils.Decompress(reader.BaseStream,
                                                this.Chunks[i].packSz,
                                                stream,
                                                bytesWritten => this.BytesWritten = prev + bytesWritten,
                                                extractParams);
                }
            }
        }
Esempio n. 4
0
        protected override void WriteDataToStream(Stream stream, SharedExtractParams extractParams, bool decompress)
        {
            var reader = extractParams.Reader;

            reader.BaseStream.Seek((long)this.Offset, SeekOrigin.Begin);
            // Reset at start since value might still be in used for a bit after
            this.BytesWritten = 0;

            if (!decompress)
            {
                StreamUtils.WriteSectionToStream(reader.BaseStream,
                                                 Math.Max(this.Size, this.RealSize), // Lazy hack, only one should be set when not compressed
                                                 stream,
                                                 bytesWritten => this.BytesWritten = bytesWritten);
            }
            else
            {
                this.WriteHeader(stream);

                try
                {
                    CompressionUtils.Decompress(reader.BaseStream,
                                                this.Size,
                                                stream,
                                                bytesWritten => this.BytesWritten = bytesWritten,
                                                extractParams);
                }
                catch (Exception ex)
                {
                    throw new Exception($"Couldn't decompress zlib texture data. Size: {this.Size}, RealSize: {this.RealSize}", ex);
                }
            }

            this.WriteChunks(stream, extractParams, decompress);
        }
Esempio n. 5
0
        /// <summary>
        /// Decompresses <paramref name="input"/> to <paramref name="output"/> with progress reports.
        /// </summary>
        /// <param name="input">The <see cref="Stream"/> with the data to decompress.</param>
        /// <param name="length">The length of the data in the <paramref name="input"/>.</param>
        /// <param name="output">The <see cref="Stream"/> to decompress to.</param>
        /// <param name="progressReport">Invokes at interval, based on <paramref name="progressInterval"/>, the amount of bytes written.</param>
        /// <param name="progressInterval">The interval at which to invoke <paramref name="progressReport"/>.</param>
        public static void Decompress(Stream input,
                                      uint length,
                                      Stream output,
                                      Action <ulong> progressReport,
                                      SharedExtractParams extractParams,
                                      long progressInterval = DefaultProgressInterval)
        {
            int   count;
            ulong written = 0;

            byte[] buffer = new byte[BufferSize];

            var raw = input.ReadBytes((int)length);

            extractParams.Inflater.Reset();
            extractParams.Inflater.SetInput(raw, 0, raw.Length);

            var sw = Stopwatch.StartNew();

            while ((count = extractParams.Inflater.Inflate(buffer)) > 0)
            {
                output.Write(buffer, 0, count);
                written += (ulong)count;

                if (sw.ElapsedMilliseconds >= progressInterval)
                {
                    progressReport?.Invoke(written);
                    sw.Restart();
                }
            }

            progressReport?.Invoke(written);
            sw.Stop();
        }
Esempio n. 6
0
        protected override void WriteDataToStream(Stream stream, SharedExtractParams extractParams, bool decompress)
        {
            var bw     = new BinaryWriter(stream);
            var reader = extractParams.Reader;

            // Reset at start since value might still be in used for a bit after
            this.BytesWritten = 0;

            if (decompress && GenerateTextureHeader)
            {
                this.WriteHeader(bw);
            }

            for (int i = 0; i < numChunks; i++)
            {
                bool  isCompressed = this.Chunks[i].packSz != 0;
                ulong prev         = this.BytesWritten;

                reader.BaseStream.Seek((long)this.Chunks[i].offset, SeekOrigin.Begin);

                if (!decompress || !isCompressed)
                {
                    StreamUtils.WriteSectionToStream(reader.BaseStream,
                                                     Chunks[i].fullSz,
                                                     stream,
                                                     bytesWritten => this.BytesWritten = prev + bytesWritten);
                }
                else
                {
                    CompressionUtils.Decompress(reader.BaseStream,
                                                this.Chunks[i].packSz,
                                                stream,
                                                bytesWritten => this.BytesWritten = prev + bytesWritten,
                                                extractParams);
                }
            }

            if (dataSizePosition > -1)
            {
                bw.WriteAt(dataSizePosition, (uint)bw.BaseStream.Length - 164);
            }
        }
Esempio n. 7
0
 public override ulong GetSizeInArchive(SharedExtractParams extractParams) => this.Compressed ? this.Size : this.RealSize;
Esempio n. 8
0
 public override ulong GetSizeInArchive(SharedExtractParams extractParams) => (ulong)Chunks.Sum(x => Compressed ? x.packSz : x.fullSz);
Esempio n. 9
0
        protected override void WriteDataToStream(Stream stream, SharedExtractParams extractParams, bool decompress)
        {
            var reader = extractParams.Reader;

            decompress = decompress && this.Compressed;
            reader.BaseStream.Position = (long)Offset;
            // Reset at start since value might still be in used for a bit after
            this.BytesWritten = 0;

            if (this.Archive.Type == ArchiveTypes.BSA_SE)
            {
                // Separate Skyrim Special Edition extraction
                ulong filesz = this.Size & 0x3fffffff;
                if (this.Archive.ContainsFileNameBlobs)
                {
                    int len = reader.ReadByte();
                    filesz -= (ulong)len + 1;
                    reader.BaseStream.Seek((long)this.Offset + 1 + len, SeekOrigin.Begin);
                }

                uint filesize = (uint)filesz;
                if (this.Size > 0 && this.Compressed)
                {
                    filesize = reader.ReadUInt32();
                    filesz  -= 4;
                }

                if (!decompress)
                {
                    StreamUtils.WriteSectionToStream(reader.BaseStream,
                                                     filesz,
                                                     stream,
                                                     bytesWritten => this.BytesWritten = bytesWritten);
                }
                else
                {
                    CompressionUtils.DecompressLZ4(reader.BaseStream,
                                                   (uint)filesz,
                                                   stream,
                                                   bytesWritten => this.BytesWritten = bytesWritten);
                }
            }
            else
            {
                // Skip ahead
                if (this.Archive.ContainsFileNameBlobs)
                {
                    reader.BaseStream.Position += reader.ReadByte() + 1;
                }

                if (!decompress)
                {
                    StreamUtils.WriteSectionToStream(reader.BaseStream,
                                                     this.Size,
                                                     stream,
                                                     bytesWritten => this.BytesWritten = bytesWritten);
                }
                else
                {
                    if (this.Compressed)
                    {
                        reader.ReadUInt32(); // Skip
                    }
                    CompressionUtils.Decompress(reader.BaseStream,
                                                this.Size - 4,
                                                stream,
                                                bytesWriten => this.BytesWritten = bytesWriten,
                                                extractParams);
                }
            }
        }
Esempio n. 10
0
 public override ulong GetSizeInArchive(SharedExtractParams extractParams) => Math.Max(this.Size, this.RealSize);