فهرست منبع

decompression method implemented

mikymod 13 سال پیش
والد
کامیت
ac39000c61
5فایلهای تغییر یافته به همراه106 افزوده شده و 32 حذف شده
  1. 10 2
      TODO.txt
  2. 71 6
      src/core/compressors/ZipCompressor.cpp
  3. 1 5
      src/core/containers/List.h
  4. 1 1
      src/core/mem/MallocAllocator.h
  5. 23 18
      tests/compressors.cpp

+ 10 - 2
TODO.txt

@@ -1,5 +1,13 @@
 TODO list:
-1 - Nel namespace filesystem, Aggiungere un compressore. esso fornirà la compressione dei dati in base agli algoritmi noti. 
+1 - Nel namespace core, Aggiungere un compressore. esso fornirà la compressione dei dati in base agli algoritmi noti. 
 Il suo utilizzo spazia fra l'internetworking (invio dei dati client-server), alla compressione dei file (ad esempio delle risorse).
 
-2 - In Queue, è necessario implementare un metodo per la distruzione/deallocazione del container
+2 - Compilatore di risorse e relativa gestione. le risorse devono essere assolutamente correte. il game engine non controlla la veridicità delle risorse.
+dovrà implementare una funzione di hash per l'indicizzazione delle risorse nel file binario specificandone il relatico offsetx. 
+Nel momento in cui viene generato il file binario con tutte le risorse al suo interno,
+si dovrà implementare un loader che prenda in input il suddetto file e carichi le risorse in base alla richiesta, che verrà fatta specificandone il nome
+
+3 - Cvar dovranno seguire un pattern JSON
+
+FIX:
+1 - In MallocAllocator, eseguendo il test compressors, se si tenta di deallocare si ottiene _invalid pointer_. l'offset è sempre di 4 byte

+ 71 - 6
src/core/compressors/ZipCompressor.cpp

@@ -25,8 +25,6 @@ uint8_t* ZipCompressor::compress(void* data, size_t in_size, size_t& out_size)
 	assert(in_size > 0);
 
 	m_data_list.clear();
-//	uint8_t* out_data = (uint8_t*)m_allocator->allocate(sizeof(uint8_t) * in_size);
-//	uint8_t* last_byte = out_data;
 
 	// memory's chunk max dimension
 	const size_t CHUNK_SIZE = 16384;
@@ -53,7 +51,6 @@ uint8_t* ZipCompressor::compress(void* data, size_t in_size, size_t& out_size)
 	{
 		size_t this_step_bytes = math::min(CHUNK_SIZE, in_size - bytes_read);
 		memcpy(in, (uint8_t*)data, sizeof(uint8_t) * this_step_bytes);
-//		read_data_block(in, this_step_bytes); 
 
 		strm.avail_in = this_step_bytes;
 		strm.next_in = in;
@@ -71,10 +68,7 @@ uint8_t* ZipCompressor::compress(void* data, size_t in_size, size_t& out_size)
 			have = CHUNK_SIZE - strm.avail_out;
 			if (have > 0)
 			{
-//				memcpy(last_byte, out, sizeof(uint8_t) * have);
 				m_data_list.push(out, have);			
-//				last_byte += sizeof(uint8_t) * have;	
-				//stream->write_data_block(out, have);
 			}
 		} while (strm.avail_out == 0);
 		assert(strm.avail_in == 0);     /* all input will be used */
@@ -94,7 +88,78 @@ uint8_t* ZipCompressor::compress(void* data, size_t in_size, size_t& out_size)
 
 uint8_t* ZipCompressor::decompress(const void* data, size_t in_size, size_t& out_size)
 {
+	m_data_list.clear();
+	
+	const size_t CHUNK_SIZE = 16384;
+	int32_t ret;
+	unsigned have;
+	z_stream strm;
+	uint8_t in[CHUNK_SIZE];
+	uint8_t out[CHUNK_SIZE];
+
+	/* allocate inflate state */
+	strm.zalloc = Z_NULL;
+	strm.zfree = Z_NULL;
+	strm.opaque = Z_NULL;
+	strm.avail_in = 0;
+	strm.next_in = Z_NULL;
+	ret = inflateInit(&strm);
+	
+	assert(ret == Z_OK);
+
+	size_t bytes_read = 0;
+
+	/* decompress until deflate stream ends or end of file */
+	do
+	{
+		size_t this_step_bytes = math::min(CHUNK_SIZE, in_size - bytes_read);
+		memcpy(in, (uint8_t*)data, sizeof(uint8_t) * this_step_bytes);
+
+		strm.avail_in = this_step_bytes;
+		strm.next_in = in;
+		if (strm.avail_in == 0)
+		{
+				break;
+		}
+
+		/* run inflate() on input until output buffer not full */
+		do {
+				strm.avail_out = CHUNK_SIZE;
+				strm.next_out = out;
+				ret = inflate(&strm, Z_NO_FLUSH);
+				
+				assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
+				
+				switch (ret) 
+				{
+					case Z_NEED_DICT:
+					{
+							ret = Z_DATA_ERROR;     /* and fall through */
+					}
+					case Z_DATA_ERROR:
+					case Z_MEM_ERROR:
+					{
+							(void)inflateEnd(&strm);
+							return false;
+					}
+				}
+				have = CHUNK_SIZE - strm.avail_out;
+				if (have > 0)
+				{
+					m_data_list.push(out, have);			
+				}
+		} while (strm.avail_out == 0);
+
+		bytes_read += this_step_bytes;
+		/* done when inflate() says it's done */
+	} while (ret != Z_STREAM_END);
+
+	/* clean up and return */
+	(void)inflateEnd(&strm);
+	
+	out_size = strm.total_out;
 
+	return m_data_list.begin();
 }
 
 }

+ 1 - 5
src/core/containers/List.h

@@ -243,7 +243,6 @@ inline void List<T>::set_capacity(uint32_t capacity)
 
 	if (capacity > 0)
 	{
-		printf("sto resizando\n");
 		T* tmp = m_array;
 		m_capacity = capacity;
 
@@ -316,12 +315,9 @@ inline uint32_t List<T>::push(const T* items, uint32_t num_items)
 {
 	if (m_capacity <= m_size + num_items)
 	{
-		reserve(m_size + num_items);
+		grow(m_size + num_items);
 	}
 
-	printf("num_items: %d\n", num_items);
-	printf("m_capacity: %d\n", m_capacity);
-	printf("m_size: %d\n", m_size);
 	memcpy(&m_array[m_size], items, sizeof(T) * num_items);
 	m_size += num_items;
 

+ 1 - 1
src/core/mem/MallocAllocator.h

@@ -48,7 +48,7 @@ private:
 	//! Holds the number of bytes of an allocation
 	struct Header
 	{
-		size_t	size;
+		uint32_t	size;
 	};
 
 	size_t		actual_allocation_size(size_t size, size_t align);

+ 23 - 18
tests/compressors.cpp

@@ -7,37 +7,42 @@ using namespace crown;
 
 int main(int argc, char** argv)
 {
-	if (argc != 2)
-	{
-		printf("Arguments must be 2");
-		return -1;
-	}
 	
 	MallocAllocator allocator;
 	ZipCompressor compressor(allocator);
 
-	char* file_name = argv[1];
-
-	const char* uncompressed_string = "foobar";
+	const char* uncompressed_string = "letstrythismotherfuckercompressionmethodoncrowngameengine.enjoy!";
+	uint8_t* compressed_string;
 	uint8_t* result;
+	size_t compr_size = 0;
 	size_t result_size = 0;
 
-	result = compressor.compress((void*)uncompressed_string, strlen(uncompressed_string), result_size);
-
-	printf("Before: ");
-	printf("Size: %d", strlen(uncompressed_string));
+	compressed_string = compressor.compress((void*)uncompressed_string, strlen(uncompressed_string), compr_size);
+	
+	printf("Uncompressed: ");
+	printf("Size: %d - ", strlen(uncompressed_string));
 	printf(uncompressed_string);
-	printf("\n");
+	printf("\n\n");
 
-	printf("After: ");
-	printf("Size: %d", result_size);
+	printf("Compressed: ");
+	printf("Size: %d - ", compr_size);
+	for (size_t i = 0; i < compr_size; i++)
+	{
+		printf("%c", compressed_string[i]);
+	}
+	printf("\n\n");
+	
+	result = compressor.decompress((void*)compressed_string, compr_size, result_size);
+	
+	printf("Uncompressed again: ");
+	printf("Size: %d - ", result_size);
 	for (size_t i = 0; i < result_size; i++)
 	{
 		printf("%c", result[i]);
 	}
-	printf("\n");
-
-//	allocator->deallocate(result);
+	printf("\n\n");
+	
+//  	allocator.deallocate(result); //FIX: invalid pointer -> check header in MallocAllocator
 	
 	return 0;
 }