public MapBlock( CompressedBlock compressed, AdjacencyTable adjacent ) { //owners = null; //tree = null; //leafs = null; Decompress( compressed, adjacent ); }
public DefaultCompressor( int rx, int ry, int zoom, ProvinceList provinces, AdjacencyTable adjacent, IDMap idmap ) { this.rx = rx; this.ry = ry; this.zoom = zoom; this.provinces = provinces; this.adjacent = adjacent; this.idmap = idmap; }
public void Decompress( CompressedBlock compressed, AdjacencyTable adjacent ) { int index = 0; // Decompress the ID table from the data stream DecompressIdTable( compressed.Data, ref index, adjacent ); // Decompress the tree from the data stream int leafcount = DecompressTree( compressed.Data, ref index ); // Create the leaf array this.leafs = new NodeData[leafcount + (leafcount % 8 == 0 ? 0 : 8-(leafcount % 8))]; // Decompress the ownership table next DecompressOwnership( compressed.Data, ref index ); // Finally, read the color data, which contains the "color" data for each leaf. DecompressColorInfo( compressed.Data, ref index ); }
/// <summary> /// Decompresses the idtable stored in the byte stream. /// </summary> /// <param name="data">The byte stream containing the compressed table. </param> /// <param name="index"></param> private static int DecompressIdTable( byte[] data, ref int index, AdjacencyTable adjacent, out Pixel[] owners ) { // -- Get a list of province ids int idCount = -1; ushort[] idTable = new ushort[IdTableSize]; do { ++idCount; idTable[idCount] = (ushort)(data[index] + ((data[index+1] & 127) << 8)); index += 2; } while ( data[index-1] < Terminator ); ++idCount; // -- Fill the ownertable owners = new Pixel[IdTableSize]; for ( int i=0; i<idCount; ++i ) { if ( idTable[i] <= Province.Count ) { owners[i] = new Pixel( 0, idTable[i] ); } else { // We're dealing with a pixel that's on a border. Decode some more... int val = idTable[i]; int color = val&1; ushort id1 = (ushort)idTable[((val>>9)&63)-4]; if ( id1 >= Province.Count ) id1 = Province.TerraIncognitaID; //ushort id2 = adjacent == null ? Province.TerraIncognitaID : adjacent.GetAdjacency( id1, (val>>1)&15 ).ID; ushort id2 = Province.TerraIncognitaID; byte riveradj = (byte)((val>>5)&15); if ( riveradj != Adjacent.Invalid && adjacent != null ) { id2 = id1; id1 = adjacent.GetAdjacency( id2, riveradj ).ID; } owners[i] = new Pixel( 0, id1, id2, (byte)(color+1) ); } } return idCount; }
public MapBlock( CompressedBlock compressed, AdjacencyTable adjacent ) { Decompress( compressed, adjacent ); }
public void Decompress( CompressedBlock compressed, AdjacencyTable adjacent ) { int index = 0; // Decompress the ID table from the data stream Pixel[] owners; int ownercount = DecompressIdTable( compressed.Data, ref index, adjacent, out owners ); // Decompress the tree from the data stream tree = DecompressTree( compressed.Data, ref index ); int leafcount = tree.CalcLeafCount(); // Create the leaf array Pixel[] leafs = new Pixel[leafcount + (leafcount % 8 == 0 ? 0 : 8-(leafcount % 8))]; // Decompress the ownership table next DecompressOwnership( compressed.Data, ref index, leafs, leafcount, owners, ownercount ); // Finally, read the color data, which contains the "color" data for each leaf. DecompressColorInfo( compressed.Data, ref index, leafs, leafcount ); // Assign the leaf data to the nodes int leafIndex = 0; PopulateNode( tree, leafs, ref leafIndex ); }
public CompressedBlock Compress( int xreal, int yreal, int zoom, ProvinceList provinces, AdjacencyTable adjacent, IDMap idmap ) { // Walk the tree, storing the info along the way MapBlockHandling.Compressor compressor; if ( provinces == null || adjacent == null || idmap == null ) compressor = new MapBlockHandling.LesserCompressor(); else compressor = new MapBlockHandling.DefaultCompressor( xreal, yreal, zoom, provinces, adjacent, idmap ); WalkTree( compressor ); // Write away idtable int datasize = compressor.IDCount*2 + compressor.Tree.Length + (compressor.LeafCount+3)/4*3; if ( compressor.IDCount == 2 ) datasize += (compressor.LeafCount+7)/8; else if ( compressor.IDCount == 3 || compressor.IDCount == 4 ) datasize += (compressor.LeafCount+3)/4; else if ( compressor.IDCount > 4 && compressor.IDCount <= 16 ) datasize += (compressor.LeafCount+1)/2; else if ( compressor.IDCount > 16 ) datasize += compressor.LeafCount; byte[] data = new byte[datasize]; int dataindex = 0; // Copy IDTable /* for ( int i=0; i<compressor.IDCount; ++i ) { data[dataindex++] = (byte)(compressor.IDTable[i] & 255); data[dataindex++] = (byte)(compressor.IDTable[i] >> 8); } */ byte[] idtable = compressor.IDTable; for ( int i=0; i<compressor.IDCount; ++i ) { for ( int t=0; t<ushort.MaxValue; ++t ) { if ( idtable[t] == i ) { data[dataindex++] = (byte)(t & 255); data[dataindex++] = (byte)(t >> 8); break; } } } data[dataindex-1] |= Terminator; byte[] tree = compressor.Tree; for ( int i=0; i<tree.Length; ++i ) { data[dataindex++] = tree[i]; } if ( compressor.IDCount == 2 ) { for ( int i=0; i<compressor.LeafCount; i+=8 ) { data[dataindex++] = (byte)( (compressor.Owners[i]) | (compressor.Owners[i+1] << 1) | (compressor.Owners[i+2] << 2) | (compressor.Owners[i+3] << 3) | (compressor.Owners[i+4] << 4) | (compressor.Owners[i+5] << 5) | (compressor.Owners[i+6] << 6) | (compressor.Owners[i+7] << 7) ); } } else if ( compressor.IDCount == 3 || compressor.IDCount == 4 ) { for ( int i=0; i<compressor.LeafCount; i+=4 ) { data[dataindex++] = (byte)( (compressor.Owners[i]) | (compressor.Owners[i+1] << 2) | (compressor.Owners[i+2] << 4) | (compressor.Owners[i+3] << 6) ); } } else if ( compressor.IDCount > 4 && compressor.IDCount <= 16 ) { for ( int i=0; i<compressor.LeafCount; i+=2 ) { data[dataindex++] = (byte)( (compressor.Owners[i]) | (compressor.Owners[i+1] << 4) ); } } else if ( compressor.IDCount > 16 ) { for ( int i=0; i<compressor.LeafCount; ++i ) { data[dataindex++] = (byte)(compressor.Owners[i]); } } // Finally, the 6-bit color values for ( int i=0; i<compressor.LeafCount; i+=4) { data[dataindex++] = (byte)((compressor.Colors[i] & 63) | ((compressor.Colors[i+1] & 63) << 6)); data[dataindex++] = (byte)(((compressor.Colors[i+1] & 63) >> 2) | ((compressor.Colors[i+2] & 63) << 4)); data[dataindex++] = (byte)(((compressor.Colors[i+2] & 63) >> 4) | ((compressor.Colors[i+3] & 63) << 2)); } return new CompressedBlock( data ); }
/// <summary> /// Decompresses the idtable stored in the byte stream. /// </summary> /// <param name="data">The byte stream containing the compressed table. </param> /// <param name="index"></param> private void DecompressIdTable( byte[] data, ref int index, AdjacencyTable adjacent ) { const int IdTableSize = 256; const int Terminator = 128; // -- Get a list of province ids int idCount = -1; ushort[] idTable = new ushort[IdTableSize]; do { ++idCount; idTable[idCount] = (ushort)(data[index] + ((data[index+1]&127) << 8)); index += 2; } while ( data[index-1] < Terminator ); ++idCount; // -- Fill the ownertable owners = new OwnerInfo[idCount]; for ( int i=0; i<idCount; ++i ) { if ( idTable[i] < Province.Count ) { owners[i] = new OwnerInfo( idTable[i] ); } else { // We're dealing with a pixel that's on a border. Decode some more... int val = idTable[i]; int color = val&1; ushort id1 = (ushort)idTable[((val>>9)&63)-4]; if ( id1 >= Province.Count ) id1 = Province.TerraIncognitaID; ushort id2 = adjacent == null ? Province.TerraIncognitaID : adjacent.GetAdjacency( id1, (val>>1)&15 ).ID; owners[i] = new OwnerInfo( id1, id2, (byte)((val>>5)&15) ); } } }