public CompressedChunk(XlBinaryReader Data)
        {
            this.CompressedChunkStart = Data.i;

            this.CompressedHeader = new CompressedChunkHeader(Data);
            this.CompressedData   = new CompressedChunkData(this.CompressedHeader, Data);
        }
示例#2
0
        //protected TokenSequence _TokenSequence;

        public CompressedChunkData(CompressedChunkHeader header, XlBinaryReader Data)
        {
            this.header = header;

            if (header.CompressedChunkFlag == (Byte)0x00)
            {
                // page 57: CompressedChunkData contains an array of CompressedChunkHeader.CompressedChunkSize
                // elements plus 3 bytes of uncompressed data
                int ArraySize = header.CompressedChunkSize + 3;
                this.Data = new Byte[ArraySize];
                int CopySize = header.CompressedChunkSize; // todo: this is my fix...
                Array.Copy(Data.ReadBytes(CopySize), 0, this.Data, 0, CopySize);

                //Array.Copy(Data, ArrayIndex, this.Data, 0, CopySize);
                //ArrayIndex += header.CompressedChunkSize;

                this.Decompress = (buffer, state) => DecompressRawChunk(buffer, state, this.Data);
            }
            else if (header.CompressedChunkFlag == (Byte)0x01)
            {
                // TODO: DO something like when compressedcurrent < compressedend -> add a new tokensequence

                // page 57: CompressedChunkData contains an array of TokenSequence elements

                var size           = Math.Min(header.CompressedChunkSize, Data.Length - Data.i);
                var tokenSequences = new List <TokenSequence>();

                int processedBytes = 0;
                while (processedBytes < size)
                {
                    int remainingBytes = size - processedBytes;
                    var tokenSequence  = new TokenSequence(Data, remainingBytes);
                    tokenSequences.Add(tokenSequence);
                    processedBytes += tokenSequence.GetSizeInBytes();
                }


                //var tokenSequenceBytes = tokenSequence.GetDataInRawBytes();
                //this.Data = tokenSequenceBytes;
                //var tokenSequenceSize = tokenSequenceBytes.Count();

                //if(tokenSequenceSize != header.CompressedChunkSize+3)
                //{
                //throw new InvalidOperationException(String.Format("CompressedChunkData Data-array size expected {0}, but was {1}", header.CompressedChunkSize+3, tokenSequenceSize));
                //}

                this.Decompress = (buffer, state) => DecompressTokenSequence(buffer, state, tokenSequences);
            }
            else
            {
                throw new Exception();
            }

            //this._TokenSequence = new TokenSequence(ref Data);
            //Data = Data.Skip(N);
        }
示例#3
0
        // 2.4.1.3.7 Compressing a DecompressedChunk
        // page 62
        private static void CompressDecompressedChunk(byte[] Data, CompressedBuffer resultBuffer, DecompressionState state)
        {
            var CompressedEnd = state.CompressedChunkStart + 4098;

            state.CompressedCurrent = state.CompressedChunkStart + 2;
            var DecompressedEnd = Math.Min(state.DecompressedChunkStart + 4096, state.DecompressedBufferEnd);

            while (state.DecompressedCurrent < DecompressedEnd && state.CompressedCurrent < CompressedEnd)
            {
                CompressTokenSequence(Data, resultBuffer, state, CompressedEnd, DecompressedEnd);
            }

            UInt16 CompressedFlag;

            if (state.DecompressedCurrent < DecompressedEnd)
            {
                CompressRawChunk(Data, resultBuffer, state, DecompressedEnd - 1);
                CompressedFlag = 0;
            }
            else
            {
                CompressedFlag = 1;
            }


            UInt16 size   = Convert.ToUInt16(state.CompressedCurrent - state.CompressedChunkStart);
            var    header = new CompressedChunkHeader(0x0000);

            PackCompressedChunkSize(Data, state, size, header);
            PackCompressedChunkFlag(Data, state, CompressedFlag, header);
            PackCompressedChunkSignature(Data, state, header);

            // SET the CompressedChunkHeader (section 2.4.1.1.5) located at CompressedChunkStart TO Header
            var bytes = BitConverter.GetBytes(header.AsUInt16());

            resultBuffer.SetByte(state.CompressedChunkStart, bytes.First());
            resultBuffer.SetByte(state.CompressedChunkStart + 1, bytes.Skip(1).Single());
        }
示例#4
0
        // Section 2.4.1.3.16
        private static void PackCompressedChunkFlag(byte[] Data, DecompressionState state, UInt16 CompressedFlag, CompressedChunkHeader header)
        {
            if (CompressedFlag != 0 && CompressedFlag != 1)
            {
                throw new ArgumentOutOfRangeException("CompressedFlag", "CompressedFlag must be 0 or 1");
            }

            UInt16 temp1  = (UInt16)(header.AsUInt16() & (ushort)0x7FFF);
            UInt16 temp2  = (UInt16)(CompressedFlag << 15);
            UInt16 result = (UInt16)(temp1 | temp2);

            header.SetFrom(result);
        }
示例#5
0
        // Section 2.4.1.3.14
        private static void PackCompressedChunkSignature(byte[] Data, DecompressionState state, CompressedChunkHeader header)
        {
            UInt16 temp   = (UInt16)(header.AsUInt16() & (ushort)0x8FFF);
            UInt16 result = (UInt16)(temp | (ushort)0x3000);

            header.SetFrom(result);
        }
示例#6
0
        // Section 2.4.1.3.13
        // page 66
        private static void PackCompressedChunkSize(byte[] Data, DecompressionState state, UInt16 size, CompressedChunkHeader header)
        {
            if (size > 4098 || size < 3)
            {
                throw new ArgumentOutOfRangeException("size", "Size must be between 3 - 4098");
            }

            UInt16 temp1  = (UInt16)(header.AsUInt16() & (ushort)(0xF000));
            UInt16 temp2  = (UInt16)(size - 3);
            UInt16 result = (UInt16)(temp1 | temp2);

            header.SetFrom(result);
        }