public DecompressedBlock( CompressedBlock block ) { root = new Node( false ); idTable = new ushort[IDTABLE_SIZE]; idCount = 0; DecodeFrom( block ); }
public void ReadBlocks( Stream stream ) { // Calculate the number of blocks to read. This depends on the zoomlevel. int blockcount = ((Map.Width >> (5+zoom)) * (Map.Height >> (5+zoom))); blocks = new CompressedBlock[blockcount]; int offsetStart = 0, offsetEnd = 0; int baseOffset = (blockcount+1) * 3 + 1; for ( int i=0; i<blockcount; ++i ) { if ( i == 0 ) { offsetStart = stream.ReadByte() + (stream.ReadByte()<<8) + (stream.ReadByte()<<16); offsetEnd = stream.ReadByte() + (stream.ReadByte()<<8) + (stream.ReadByte()<<16); } else { offsetStart = offsetEnd; offsetEnd = stream.ReadByte() + (stream.ReadByte()<<8) + (stream.ReadByte()<<16); } blocks[i] = new CompressedBlock( baseOffset+offsetStart, offsetEnd-offsetStart, this ); // Defer reading the block data till later. } // Read another byte. The last offset is stored as a 4-byte integer, but only 3 bytes where read in the loop before. int zero = stream.ReadByte(); // Read all the actual data afterwards for ( int i=0; i<blockcount; ++i ) { blocks[i].Read( stream ); } sourceFilename = stream is FileStream ? ((FileStream)stream).Name : ""; }
public void DecodeFrom( CompressedBlock block ) { const int INVALID_ADJ = 15; const int TERMINATOR = 128; Install install = block.Parent.Install; byte[] data = block.Data; for ( int i=0; i<IDTABLE_SIZE; ++i ) idTable[i] = ushort.MaxValue; int index = 0; idCount = -1; // Get a list of province ids do { ++idCount; idTable[idCount] = (ushort)(data[idCount<<1] + ((data[(idCount<<1)+1]&127) << 8)); index += 2; } while ( data[(idCount<<1)+1] < TERMINATOR ); ++idCount; // Normalize the IDs... Basically, we're stripping some of that data away which we don't need (mainly to do with borders). for ( int i=0; i<idCount; ++i ) { if ( idTable[i] <= Province.MaxID ) continue; ushort id = idTable[((idTable[i]>>9) & 63)-4]; if( id > Province.MaxID ) id = install.Provinces.TerraIncognita.ID; else { int river = (idTable[i]>>5) & 15; if ( river != INVALID_ADJ ) id = install.Provinces[id].GetNeighbor( river ).ID; idTable[i] = id; } } // Build the tree. DecompressorState decompstate = new DecompressorState( index, ref data ); BuildTree( root, decompstate, 5 ); index = decompstate.GetFinalNodeIndex(); // Define ownership and colors tables int numLeaves = decompstate.NumOfLeaves; int sizeLeaves = decompstate.SizeOfLeaves; byte[] colors = new byte[decompstate.SizeOfLeaves + (4-(decompstate.SizeOfLeaves % 4))]; ushort[] ownership = null; decompstate = null; if ( idCount == 1 ) { ownership = new ushort[numLeaves]; for ( int i=0; i<numLeaves; ++i ) ownership[i] = idTable[0]; } else if ( idCount == 2 ) { ownership = new ushort[numLeaves + (8-(numLeaves % 8))]; for ( int i=0; i<numLeaves; ++index ) { ownership[i++] = idTable[(data[index] >> 0) & 1]; ownership[i++] = idTable[(data[index] >> 1) & 1]; ownership[i++] = idTable[(data[index] >> 2) & 1]; ownership[i++] = idTable[(data[index] >> 3) & 1]; ownership[i++] = idTable[(data[index] >> 4) & 1]; ownership[i++] = idTable[(data[index] >> 5) & 1]; ownership[i++] = idTable[(data[index] >> 6) & 1]; ownership[i++] = idTable[(data[index] >> 7) & 1]; } } else if ( idCount <= 4 ) { ownership = new ushort[numLeaves + (4-(numLeaves % 4))]; for ( int i=0; i<numLeaves; ++index ) { ownership[i++] = idTable[(data[index] >> 0) & 3]; ownership[i++] = idTable[(data[index] >> 2) & 3]; ownership[i++] = idTable[(data[index] >> 4) & 3]; ownership[i++] = idTable[(data[index] >> 6) & 3]; } } else if ( idCount <= 16 ) { ownership = new ushort[numLeaves + (2-(numLeaves % 2))]; for ( int i=0; i<numLeaves; index++ ) { ownership[i++] = idTable[(data[index] >> 0) & 15]; ownership[i++] = idTable[(data[index] >> 4) & 15]; } } else if ( idCount > 16 ) { ownership = new ushort[numLeaves]; for ( int i=0; i<ownership.Length; ++i, ++index ) ownership[i] = idTable[data[index]]; } // Read in color table // Finally, read the leaf data. This part contains the "color" data for each leaf. for ( int i=0; i<sizeLeaves; ) { colors[i++] = (byte)(data[index] & 63); colors[i++] = (byte)((data[index] >> 6 | data[index+1] << 2) & 63); colors[i++] = (byte)((data[index+1] >> 4 | data[index+2] << 4) & 63); colors[i++] = (byte)(data[index+2] >> 2); index += 3; } // Fill them into the tree PopulatorState popstate = new PopulatorState( ref ownership, ref colors ); PopulateTree( root, popstate ); }
public void EncodeTo( CompressedBlock block ) { }