📄 block.c
字号:
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 + -