⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 block.c

📁 zzip-zzlib-src.zip. A new archiver that uses a BWT algorithm to achieve superior compression. The
💻 C
📖 第 1 页 / 共 3 页
字号:
		GET_TSC(p2);

		STAT_ADD_TIME(time_st1, p2, p1);
		STAT_ADD_SIZE(kb_st1, len2);

		if (last_error != OK) return -1;
		
		/*- End ---------- Arith Compression --*/
		
		/* if we can't compress the block, we get the original block */
		if ((tot1+tot2) > len_max)
		{
			err = -1;
			
#ifdef ZZLIB
			if (from_file == false)
			{
				mem.buffer8 = MyFree(mem.buffer8);
				mem.buffer8 = (uint8*)MyMalloc(sizeof(uint8) * len_in);
				if (last_error != OK) return -1;
				buf_out1 = mem.buffer8;
				
				memcpy(buf_out1, buffer_in, sizeof(uint8) * len_in);
				tot1 = len_in;
			}
			else
#endif /* ZZLIB */
			{
				mem.buffer8 = MyFree(mem.buffer8);
				mem.buffer8 = (uint8*)MyMalloc(sizeof(uint8) * block_len);
				if (last_error != OK) return -1;
				buf_out1 = mem.buffer8;
				
				FSEEK_I(pos, SEEK_SET);
				if (last_error != OK) return -1;
				
				tot1 = READ_F(buf_out1, block_len);
				if (last_error == UNEXPECTED_EOF) last_error = OK;
				if (last_error != OK) return -1;
			}
			
			len_max = tot1;
		}
	} /* (len > 50) */
	else 
	{
		buf_out1 = buffer1;
		err = -1;
		tot1 = len;
	}

	/*- Beginning ---- Writings -----------*/

	/*  status
     *   1   1   1   1   1   1   1
	 *   6   5   4   3   2   1   0   9   8   7   6   5   4   3   2   1
	 * |err|                       |ffb|eng|   mm_type |      type |rle|
	 */
	status = 0;
	status |= ff_bug;
	status <<= 1;
	status |= block.english_encoding;
	status <<= 3;
	status |= block.mm_type;
	status <<= 3;
	status |= block.type;
	status <<= 1;
	status |= block.rle_encoding;

	if (err == -1) status |= 32768;

	/* we add a small margin, in case... */
	len_max += 32;

#ifdef ZZLIB
	if (from_file == false)
	{
		WRITE_M(&len_max, sizeof(len_max));
		WRITE_M(&block.crc, sizeof(block.crc));
		if ((status & 32768) == 0)
		{
			WRITE_M(&status, sizeof(status));
			WRITE_M(&len, sizeof(len));
			WRITE_M(&len2, sizeof(len2));
			WRITE_M(&first, sizeof(first));
			WRITE_M(&block.mtf_max_char, sizeof(block.mtf_max_char));
			WRITE_M(&tot2, sizeof(tot2));
			WRITE_M(buf_out2, sizeof(uint8) * tot2);
		}
		else 
		{ 
			WRITE_M(&status, sizeof(status)); 
		}
		WRITE_M(&tot1, sizeof(tot1));
		WRITE_M(buf_out1, sizeof(uint8) * tot1);
	}
	else
#endif /* ZZLIB */
	{
		WRITE_F(&len_max, sizeof(len_max));
		WRITE_F(&block.crc, sizeof(block.crc));
		if ((status & 32768) == 0)
		{
			WRITE_F(&status, sizeof(status));
			WRITE_F(&len, sizeof(len));
			WRITE_F(&len2, sizeof(len2));
			WRITE_F(&first, sizeof(first));
			WRITE_F(&block.mtf_max_char, sizeof(block.mtf_max_char));
			WRITE_F(&tot2, sizeof(tot2));
			WRITE_F(buf_out2, sizeof(uint8) * tot2);
		}
		else 
		{ 
			WRITE_F(&status, sizeof(status)); 
		}
		WRITE_F(&tot1, sizeof(tot1));
		WRITE_F(buf_out1, sizeof(uint8) * tot1);
		
		CHECK_IO_W();
		if (last_error != OK) return -1;

		FTELL_O(fin);
		if (last_error != OK) return -1;
	}
	
#ifdef _DEBUG
	printf("1 (compression) : status=%u len=%u len2=%u first=%u tot2=%u tot1=%u\n", status, len, len2, first, tot2, tot1);
	printf("2 (compression) : mtf_max_char=%u english=%u mm_type=%u type=%u rle=%u \n", block.mtf_max_char, block.english_encoding, block.mm_type, block.type, block.rle_encoding);
#endif /* _DEBUG */
	
	/*- End ---------- Writings -----------*/

	mem.buffer8 = MyFree(mem.buffer8);

#ifdef ZZLIB
	if (from_file == false) return (uint32)(buffer_in - sav_buffer_in);
	else
#endif /* ZZLIB */
	return (uint32)(fin - deb);
}

#endif /* !SFX */

/*---------------------------------------------*/

static
#ifdef ZZLIB
sint32 UncompressBlock(modes mode, 
					   bool  to_file, 
					   uint8 *buffer_in)
#else  /* ZZLIB */
sint32 UncompressBlock(modes mode)
#endif /* ZZLIB */
{
	bool   ff_bug = false;
	uint16 status;
	uint32 len = 0, len2 = 0, len_max = 0, first = 0, tot1 = 0, tot2 = 0;
	uint8  *bufferin1 = NULL, *bufferin2 = NULL, *bufferout = NULL;
#ifdef GET_STAT
	uint64 p1, p2;
#endif /* GET_STAT */

#ifdef ZZLIB
	uint8 *sav_buffer_in = buffer_in;

	if (to_file == false)
	{
		READ_M(&len_max, sizeof(len_max));
		READ_M(&block.crc, sizeof(block.crc));
		READ_M(&status, sizeof(status));

		if ((status & 32768) == 0)
		{
			ff_bug					= (status >> 8) & (1);
			block.english_encoding	= (status >> 7) & (1);
			block.mm_type			= (status >> 4) & (1 + 2 + 4);
			block.type				= (status >> 1) & (1 + 2 + 4);
			block.rle_encoding		= (status >> 0) & (1);
			READ_M(&len, sizeof(len));
			READ_M(&len2, sizeof(len2));
			READ_M(&first, sizeof(first));
			READ_M(&block.mtf_max_char, sizeof(block.mtf_max_char));
			
			mem.buffer8 = (uint8*)MyMalloc(sizeof(uint8) * len_max * 5 + 32 * 2);
			if (last_error != OK) return -1;
			bufferout = mem.buffer8;
			bufferin1 = (uint8*)ROUND32(bufferout + len_max);
			bufferin2 = (uint8*)ROUND32(bufferin1 + len_max);
			
			READ_M(&tot2, sizeof(tot2));
			READ_M(bufferin2, sizeof(uint8) * tot2);
		}		
		else 
		{ 
			mem.buffer8 = (uint8*)MyMalloc(sizeof(uint8) * len_max * 1);
			if (last_error != OK) return -1;
			bufferin1 = mem.buffer8;
		}
		READ_M(&tot1, sizeof(tot1));	
		READ_M(bufferin1, sizeof(uint8) * tot1);
	
		buffer_in = sav_buffer_in;
	}
	else
#endif /* ZZLIB */
	{
		READ_F(&len_max, sizeof(len_max));
		READ_F(&block.crc, sizeof(block.crc));
		READ_F(&status, sizeof(status));
		
		CHECK_IO_R();
		if (last_error != OK) return -1;

		if ((status & 32768) == 0)
		{
			ff_bug					= (status >> 8) & (1);
			block.english_encoding	= (status >> 7) & (1);
			block.mm_type			= (status >> 4) & (1 + 2 + 4);
			block.type				= (status >> 1) & (1 + 2 + 4);
			block.rle_encoding		= (status >> 0) & (1);
			READ_F(&len, sizeof(len));
			READ_F(&len2, sizeof(len2));
			READ_F(&first, sizeof(first));
			READ_F(&block.mtf_max_char, sizeof(block.mtf_max_char));
			
			mem.buffer8 = (uint8*)MyMalloc(sizeof(uint8) * len_max * 5 + 32 * 2);
			if (last_error != OK) return -1;
			bufferout = mem.buffer8;
			bufferin1 = (uint8*)ROUND32(bufferout + len_max);
			bufferin2 = (uint8*)ROUND32(bufferin1 + len_max);
			
			READ_F(&tot2, sizeof(tot2));
			READ_F(bufferin2, sizeof(uint8) * tot2);
		}		
		else 
		{ 
			mem.buffer8 = (uint8*)MyMalloc(sizeof(uint8) * len_max * 1);
			if (last_error != OK) return -1;
			bufferin1 = mem.buffer8;
		}
		READ_F(&tot1, sizeof(tot1));	
		READ_F(bufferin1, sizeof(uint8) * tot1);
		
		CHECK_IO_R();
		if (last_error != OK) return -1;
	}
	
	
#ifdef _DEBUG
	printf("1 (decompression) : status=%u len=%u len2=%u first=%u tot2=%u tot1=%u\n", status, len, len2, first, tot2, tot1);
	printf("2 (decompression) : mtf_max_char=%u english=%u mm_type=%u type=%u rle=%u \n", block.mtf_max_char, block.english_encoding, block.mm_type, block.type, block.rle_encoding);
#endif /* _DEBUG */

	if ((status & 32768) == 0)
	{
		block.buffer        = bufferin1;
		block.buffer_length = bufferin1 + tot1;

		GET_TSC(p1);
		Unzip_SM0(len, bufferout);
		GET_TSC(p2);

		STAT_ADD_TIME(time_st0, p2, p1);
		STAT_ADD_SIZE(kb_st0, len);

		if (last_error != OK) return -1;

		block.buffer        = bufferin2;
		block.buffer_length = bufferin2 + tot2;
		
		GET_TSC(p1);
		Unzip_SM1(len2, bufferin1);
		GET_TSC(p2);

		STAT_ADD_TIME(time_st1, p2, p1);
		STAT_ADD_SIZE(kb_st1, len2);

		if (last_error != OK) return -1;
		
		GET_TSC(p1);

		UnSplit(bufferout, bufferout + len, bufferin1);

		M1FF2_Decoding(bufferout, bufferout + len);

		GET_TSC(p2);

		STAT_ADD_TIME(time_mtf, p2, p1);
		STAT_ADD_SIZE(kb_mtf, len);

		GET_TSC(p1);
		BWT_Decoding(len, first, bufferout, (uint32*)bufferin1);
		GET_TSC(p2);

		STAT_ADD_TIME(time_bwt1, p2, p1);
		STAT_ADD_SIZE(kb_bwt, len);

		if (last_error != OK) return -1;

		if (ff_bug == true)
			bufferout[len - 1] += bufferout[len - 2];

		if (block.english_encoding == true)
		{
			GET_TSC(p1);
			len = UnFilter2(bufferout, bufferin1, bufferout + len);
			memcpy(bufferout, bufferin1, len);
			GET_TSC(p2);

			STAT_ADD_TIME(time_txt, p2, p1);
		}

		if (block.type == TEXT)
		{
			GET_TSC(p1);
			len = UnFilter1(bufferout, len);
			GET_TSC(p2);

			STAT_ADD_TIME(time_txt, p2, p1);
			STAT_ADD_SIZE(kb_txt, len);
		}

		if (block.type == BIN || block.type == WIN_EXE)
		{
			GET_TSC(p1);
			Reverse_Block(bufferout, bufferout + len);
			GET_TSC(p2);

			STAT_ADD_TIME(time_txt, p2, p1);
			STAT_ADD_SIZE(kb_txt, len);
		}
		
		if (block.type == WIN_EXE)	
		{
			GET_TSC(p1);
			Win32_Decoding(bufferout, bufferout + len);
			GET_TSC(p2);

			STAT_ADD_TIME(time_txt, p2, p1);
		}

		if (block.mm_type != 0)
		{
			GET_TSC(p1);
			MM_Decoding(bufferout, bufferout + len);
			GET_TSC(p2);

			STAT_ADD_TIME(time_mm, p2, p1);
			STAT_ADD_SIZE(kb_mm, len);
		}

		if (block.rle_encoding == true) 
		{
			GET_TSC(p1);
			len = RLE_Decoding(bufferout, bufferin1, bufferout + len);
			memcpy(bufferout, bufferin1, len);
			GET_TSC(p2);

			STAT_ADD_TIME(time_rle, p2, p1);
			STAT_ADD_SIZE(kb_rle, len);
		}

		/* trick for 'Canterbury Corpus: kennedy.xls' !*/
		if (block.mm_type == 6)
		{
			uint  i;
			uint8 *b8_out, *b8, *bufferout2 = bufferin1;

			memcpy(bufferout2, bufferout, 2320);

			b8 = bufferout + 2320;
			for (i = 0; i < 13; ++i)
				for (b8_out = bufferout2 + 2320 + i; b8_out < bufferout2 + len; b8_out += 13)
					*b8_out = *b8++ + *(b8_out-13);

			memcpy(bufferout + 2320, bufferout2 + 2320, len - 2320);
		}

		STAT_ADD_SIZE(kb_tot, len);

		if (block.crc != Crc32_2(bufferout, bufferout + len))
		{
			last_error = CRC_ERROR;
			return -1;
		}

		if (mode == UNCOMPRESS)
		{
#ifdef ZZLIB
			if (to_file == false) { WRITE_M(bufferout, sizeof(uint8) * len); }
			else
#endif /* ZZLIB */
			WRITE_F(bufferout, sizeof(uint8) * len);
		}
	}
	else 
	{
		STAT_ADD_SIZE(kb_tot, tot1);

		if (block.crc != Crc32_2(bufferin1, bufferin1 + tot1))
		{
			last_error = CRC_ERROR;
			return -1;
		}

		len = tot1;
		if (mode == UNCOMPRESS)
		{
#ifdef ZZLIB
			if (to_file == false) { WRITE_M(bufferin1, sizeof(uint8) * len); }
			else
#endif /* ZZLIB */
			WRITE_F(bufferin1, sizeof(uint8) * len);
		}
	}

	mem.buffer8 = MyFree(mem.buffer8);

	if (mode == UNCOMPRESS)
	{
#ifdef ZZLIB
		if (to_file == true)
#endif /* ZZLIB */
		{
			CHECK_IO_W();
			if (last_error != OK) return -1;
		}
	}

	return len;
}

/*---------------------------------------------*/

#ifndef SFX

static
void Compress()
{
	uint		i;
	block_types	block_type = NO_TYPE;
    struct stat	buf_stat;
	slong		p1, p3;
	uint32		out_size;
#ifndef ZZLIB
	sint32		l = 0;
#endif /* ZZLIB */

	if (stat(session->input_filename, &buf_stat) == -1) IO_ERROR();
	session->head_file.name          = session->input_filename;
	session->head_file.time          = buf_stat.st_mtime;
	session->head_file.attributes    = buf_stat.st_mode;
	session->head_file.original_size = buf_stat.st_size;

	if ((session->input_file = fopen(session->input_filename, "rb")) == NULL) 
	{ 
		last_error = CANNOT_OPEN_INPUT_FILE;
		return;
	}
				
	FTELL_O(p1);
	Write_Header_File();

	if (last_error != OK) return;

	block.type  = session->type;
	block.multimedia_test = session->multimedia_test;

	out_size = 0;
	for (i = 0; feof(session->input_file) == 0; ++i)
	{
		if (block.type != WIN_EXE) block.type = session->type;
		block.compression_mode = session->compression_mode;

#ifdef ZZLIB
		out_size += CompressBlock(1, NULL, 0);
		if (last_error != OK) return;
		if (i == 0) block_type = block.type;
	}
#else  /* ZZLIB*/
		out_size += CompressBlock();
		if (last_error != OK) return;
		if (i == 0) block_type = block.type;
		FTELL_I(l);
		VERBOSE printf("%#04.1f%%\b\b\b\b\b", (((float)l) * 100) / session->head_file.original_size);
	}
	VERBOSE printf("      \b\b\b\b\b\b\b");
#endif /* ZZLIB */
	block.type = block_type;
	session->head_file.nb_of_block = i;

	FTELL_O(p3);
	if (last_error != OK) return;

	if (fclose(session->input_file)) { last_error = CANNOT_CLOSE_INPUT_FILE; return; }
	session->input_file = NULL;

	FSEEK_O(p1, SEEK_SET);
	if (last_error != OK) return;

	session->head_file.packed_size = out_size;
	Write_Header_File();
	if (last_error != OK) return;

	FSEEK_O(p3, SEEK_SET);
	if (last_error != OK) return;

	session->input_total += session->head_file.original_size;
	session->output_total += out_size;
}

#endif /* !SFX */

/*---------------------------------------------*/

static
void Uncompress(modes mode)
{
	struct utimbuf filetime;
	slong  t1 = 0, t2 = 0;
	uint   i = 0;
	uint32 l = 0;

	FTELL_I(t1);
	if (last_error != OK) return;

	Read_Header_File();
	if (last_error != OK) return;
	
	if (mode == UNCOMPRESS)
	{
		/* we strip the path before the file name */
		session->output_filename = strrchr(session->head_file.name, SEP_PATH);
		if (session->output_filename != NULL)
		{
			if (session->with_path == 0) session->output_filename++;
			else
			{
				struct stat st_buf;
				char *p, *path = session->head_file.name;
				
				for (p = path; *p; ++p)
				{
					if (*p == SEP_PATH)
					{
						*p = 0;
						if (stat(path, &st_buf) != 0 
							|| (st_buf.st_mode & (S_IFDIR|S_IREAD)) != (S_IFDIR|S_IREAD))
						{
							if (mkdir(path MKDIR_OPTIONS) == -1) IO_ERROR();
						}
						*p = SEP_PATH;
					}
				}
				
				session->output_filename = session->head_file.name;
			}
		}
		else session->output_filename = session->head_file.name;
		
		if ((session->output_file = fopen(session->output_filename, "wb")) == NULL)
		{ 
			last_error = CANNOT_OPEN_OUTPUT_FILE; 
			return;
		}
	}
	else session->output_filename = session->head_file.name;

	for (i = 0; i < session->head_file.nb_of_block; ++i)
	{
#ifdef ZZLIB
		l += UncompressBlock(mode, 1, NULL);
		if (last_error != OK) return;
	}
#else  /* ZZLIB */
		l += UncompressBlock(mode);
		if (last_error != OK) return;
		VERBOSE printf(" %#04.1f%%\b\b\b\b\b\b", (((float)l) * 100) / session->head_file.original_size);
	}
	VERBOSE printf("      \b\b\b\b\b\b\b");
#endif /* ZZLIB */

	session->output_total += l;
	
	FTELL_I(t2);
	session->input_total += t2 - t1;

	if (mode == UNCOMPRESS)
	{
		if (fclose(session->output_file)) 
		{ 
			last_error = CANNOT_CLOSE_OUTPUT_FILE; 
			return; 
		}
		session->output_file = NULL;
		
		filetime.actime = session->head_file.time;
		filetime.modtime = session->head_file.time;
		if (utime(session->output_filename, &filetime) == -1) IO_ERROR();
		if (chmod(session->output_filename, session->head_file.attributes) == -1) IO_ERROR();
	}
}

/*---------------------------------------------*/

#ifdef ZZLIB

DLL_EXPORT int ZzCompressBlock(unsigned char *buffer, 
							   unsigned int  size, 
							   unsigned int  compression_mode, 
							   unsigned int  multimedia_test)
{
	int len;

	last_error = OK;

	if (buffer == NULL

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -