Exemplo n.º 1
0
		public void CompressVoxelData( ushort[] data, out byte[] result, out int bytes_used )
		{
			BitStream stream = new BitStream();
			int len = data.Length;
			int n;
			List<ushort> types = new List<ushort>();
			for( n = 0; n < len; n++ )
			{
				if( !types.Contains( data[n] ) )
					types.Add( data[n] );
			}
			int bits = BitStream.GetMinBitsNeededForValue( types.Count - 1 ); // 4 is 0,1,2,3; needs only 2 bits...
			//bits = (bits + 7 ) & 0xf8;
			stream.Seek( 16 ); // seek bit count
			stream.Write( (byte)bits, 8 );
			stream.Write( (uint)types.Count-1, bits );
			foreach( ushort type in types )
				stream.Write( type, 16 );
			ushort prior_cube = 0xFFFF, cube;
			uint index = 0;
			int count = 0;
            for( n = 0; n < len; n++ )
			{
				cube = data[n];
				if( prior_cube != cube )
				{
					if( count > 0 )
						WriteCubes( stream, bits, (uint)count, index );
					index = (uint)types.IndexOf( cube );
					prior_cube = cube;
					count = 1;
				}
				else
					count++;
			}
			WriteCubes( stream, bits, (uint)count, index );

			stream.GetBytes( out result, out bytes_used );
			result[0] = (byte)(( bytes_used ) & 0xFF);
			result[1] = (byte)( ( bytes_used ) >> 8);
			if( bytes_used < 20 )
				return;

			MemoryStream final_stream = new MemoryStream();
			final_stream.Seek( 2, SeekOrigin.Begin );
			//DeflateStream gz_stream = new DeflateStream( final_stream, CompressionMode.Compress );
			//GZipStream gz_stream = new GZipStream( final_stream, CompressionMode.Compress );
			GZipStream gz_stream = new GZipStream( final_stream, CompressionLevel.Fastest );
			//for( n = 2; n < bytes_used; n++ )
			//	gz_stream.WriteByte( result[n] );
			gz_stream.Write( result, 2, bytes_used - 2 );
			gz_stream.Close();
			result = final_stream.ToArray();//.GetBuffer();
			Log.log( "Compressed another {0}%", (float)( 100.0f * (float)( bytes_used - result.Length ) / ( bytes_used - 2 ) ) );
			// store old length so we know how much to request decompressing.
			result[0] = (byte)( ( bytes_used ) & 0xFF );
			result[1] = (byte)( ( bytes_used ) >> 8 );
			bytes_used = result.Length;// (int)final_stream.Length;
			gz_stream.Dispose();
		}