Пример #1
0
        /// <summary>Compress a buffer in native memory</summary>
        /// <param name="buffer">Pointer to the native memory buffer to compress</param>
        /// <param name="count">Number of bytes to compress</param>
        /// <param name="output">Where to write the compressed words</param>
        /// <returns>Number of extra bits that where output in the last literal word (or none if 0)</returns>
        internal static unsafe int CompressToUnsafe(byte *buffer, int count, CompressedBitmapWriter output)
        {
            // Simplified algorithm:
            // 1) read 31 bits from input (BE)
            // 2) if not all 0 (or all 1), then output a literal word (MSB set to 0), and jump back to step 1)
            // 3) set LENGTH = 1, FILL_BIT = 0 (or 1)
            // 4) Peek at next 31 bits, and if they are still all 0 (or 1), increment N, and jump back to step 4)
            // 5) output a repeat word, with MSB set to 1, followed by FILL_BIT, and then LENGTH-1 (30 bit), and jump back to step 1)

            // Optimizations:
            // - for very small inputs (3 bytes or less) we return a single literal word
            // - we read 64 bits at a time in the buffer, because it fits nicely in an UInt64 register

            var bucket = new UncompressedWordReader(buffer, count);

            uint word;

            while ((word = bucket.Read()) != UncompressedWordReader.NotEnough)
            {
                output.Write(word);
            }

            // if there are remaining bits, they are padded with 0 and written as a literal
            int bits = bucket.Bits;

            if (bits > 0)
            {
                //note: MSB will already be 0
                word = bucket.ReadLast();
                output.Write(word);
            }

            // write the header
            output.Pack();

            return(bits);
        }
Пример #2
0
		/// <summary>Compress a buffer in native memory</summary>
		/// <param name="buffer">Pointer to the native memory buffer to compress</param>
		/// <param name="count">Number of bytes to compress</param>
		/// <param name="output">Where to write the compressed words</param>
		/// <returns>Number of extra bits that where output in the last literal word (or none if 0)</returns>	
		internal static unsafe int CompressToUnsafe(byte* buffer, int count, CompressedBitmapWriter output)
		{
			// Simplified algorithm:
			// 1) read 31 bits from input (BE)
			// 2) if not all 0 (or all 1), then output a literal word (MSB set to 0), and jump back to step 1)
			// 3) set LENGTH = 1, FILL_BIT = 0 (or 1)
			// 4) Peek at next 31 bits, and if they are still all 0 (or 1), increment N, and jump back to step 4)
			// 5) output a repeat word, with MSB set to 1, followed by FILL_BIT, and then LENGTH-1 (30 bit), and jump back to step 1)

			// Optimisations:
			// - for very small inputs (3 bytes or less) we return a single literal word
			// - we read 64 bits at a time in the buffer, because it fits nicely in an UInt64 register

			var bucket = new UncompressedWordReader(buffer, count);

			uint word;
			while ((word = bucket.Read()) != UncompressedWordReader.NotEnough)
			{
				output.Write(word);
			}

			// if there are reamining bits, they are padded with 0 and written as a literal
			int bits = bucket.Bits;
			if (bits > 0)
			{
				//note: MSB will already be 0
				word = bucket.ReadLast();
				output.Write(word);
			}

			// write the header
			output.Pack();

			return bits;
		}