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

📄 extract.cpp

📁 A*算法 A*算法 A*算法 A*算法A*算法A*算法
💻 CPP
字号:
/* *  extract.c -- global extracting function for all known file compressions *               in a MPQ archive. * *  Copyright (C) 2003 Maik Broemme <mbroemme@plusserver.de> * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdlib.h>#include <zlib.h>#include <string.h>#include <stdio.h>#include "mpq.h"#include "explode.h"#include "huffman.h"#include "wave.h"/* *  Support functions for PKWARE data compression library. * *  Function loads data from the input buffer. Used by mpq_pkzip *  "implode" and "explode" function as user-defined callback. *  Returns number of bytes loaded. * *  char * buf          - Pointer to a buffer where to store loaded data *  unsigned int * size - Max. number of bytes to read *  void * param        - Custom pointer, parameter of implode/explode */static unsigned int libmpq_pkzip_read_input_data(char *buf, unsigned int *size, void *param) {	pkzip_data *info = (pkzip_data *)param;	unsigned int max_avail = (info->in_bytes - info->in_pos);	unsigned int to_read = *size;	/* Check the case when not enough data available */	if (to_read > max_avail) {		to_read = max_avail;	}	/* Load data and increment offsets */	memcpy(buf, info->in_buf + info->in_pos, to_read);	info->in_pos += to_read;	return to_read;}/* *  Support functions for PKWARE data compression library. * *  Function for store output data. Used by mpq_pkzip "implode" and *  "explode" as user-defined callback. * *  char * buf          - Pointer to data to be written *  unsigned int * size - Number of bytes to write *  void * param        - Custom pointer, parameter of implode/explode */static void libmpq_pkzip_write_output_data(char *buf, unsigned int *size, void *param) {	pkzip_data *info = (pkzip_data *)param;	unsigned int max_write = (info->max_out - info->out_pos);	unsigned int to_write = *size;	/* Check the case when not enough space in the output buffer */	if (to_write > max_write) {		to_write = max_write;	}	/* Write output data and increments offsets */	memcpy(info->out_buf + info->out_pos, buf, to_write);	info->out_pos += to_write;}int libmpq_pkzip_decompress(char *out_buf, int *out_length, char *in_buf, int in_length) {	pkzip_data info;					/* Data information */	char *work_buf = (char*)malloc(LIBMPQ_PKZIP_EXP_BUFFER_SIZE);	/* mpq_pkzip work buffer */	/* Fill data information structure */	info.in_buf   = in_buf;	info.in_pos   = 0;	info.in_bytes = in_length;	info.out_buf  = out_buf;	info.out_pos  = 0;	info.max_out  = *out_length;	/* Do the decompression */	libmpq_pkzip_explode(libmpq_pkzip_read_input_data, libmpq_pkzip_write_output_data, work_buf, &info);	*out_length = info.out_pos;	free(work_buf);	return 0;}int libmpq_wave_decompress_mono(char *out_buf, int *out_length, char *in_buf, int in_length) {	*out_length = libmpq_wave_decompress((unsigned char *)out_buf, *out_length, (unsigned char *)in_buf, in_length, 1);	return 1;}int libmpq_wave_decompress_stereo(char *out_buf, int *out_length, char *in_buf, int in_length) {	*out_length = libmpq_wave_decompress((unsigned char *)out_buf, *out_length, (unsigned char *)in_buf, in_length, 2);	return 1;}int libmpq_zlib_decompress(char *out_buf, int *out_length, char *in_buf, int in_length) {	z_stream z;					/* Stream information for zlib */	int result;	/* Fill the stream structure for zlib */	z.next_in   = (Bytef *)in_buf;	z.avail_in  = (uInt)in_length;	z.total_in  = in_length;	z.next_out  = (Bytef *)out_buf;	z.avail_out = *out_length;	z.total_out = 0;	z.zalloc    = NULL;	z.zfree     = NULL;	/* Initialize the decompression structure. Storm.dll uses zlib version 1.1.3 */	if ((result = inflateInit(&z)) == 0) {		/* Call zlib to decompress the data */		result = inflate(&z, Z_FINISH);		*out_length = z.total_out;		inflateEnd(&z);	}	return result;}/* *  Huffmann decompression routine. The in_length parameter is not used, but needs *  to be specified due to compatibility reasons. * *  1500F5F0 */int libmpq_huff_decompress(char *out_buf, int *out_length, char *in_buf, int in_length) {	struct huffman_tree		*ht = (huffman_tree*)malloc(sizeof(struct huffman_tree));	struct huffman_input_stream	*is = (huffman_input_stream	*)malloc(sizeof(struct huffman_input_stream));	struct huffman_tree_item	*hi = (huffman_tree_item	*)malloc(sizeof(struct huffman_tree_item));	memset(ht, 0, sizeof(struct huffman_tree));	memset(is, 0, sizeof(struct huffman_input_stream));	memset(hi, 0, sizeof(struct huffman_tree_item));	/* Initialize input stream */	is->bit_buf  = *(unsigned long *)in_buf;	in_buf      += sizeof(unsigned long);	is->in_buf   = (unsigned char *)in_buf;	is->bits     = 32;	/* Initialize the Huffmann tree for decompression */	libmpq_huff_init_tree(ht, hi, LIBMPQ_HUFF_DECOMPRESS);	*out_length = libmpq_huff_do_decompress(ht, is, (unsigned char *)out_buf, *out_length);	free(hi);	free(is);	free(ht);	return 0;}int libmpq_multi_decompress(char *out_buf, int *pout_length, char *in_buf, int in_length) {	char		*temp_buf = NULL;		/* Temporary storage for decompressed data */	char		*work_buf = NULL;		/* Where to store decompressed data */	int		out_length = *pout_length;	/* For storage number of output bytes */	unsigned	fDecompressions1;		/* Decompressions applied to the block */	unsigned	fDecompressions2;		/* Just another copy of decompressions applied to the block */	int		count = 0;			/* Counter for every use */	int		entries = (sizeof(dcmp_table) / sizeof(decompress_table));	int		i;	/* If the input length is the same as output, do nothing. */	if (in_length == out_length) {		if (in_buf == out_buf) {			return 1;		}		memcpy(out_buf, in_buf, in_length);		return 1;	}	/* Get applied compression types and decrement data length */	fDecompressions1 = fDecompressions2 = (unsigned char)*in_buf++;	in_length--;	/* Search decompression table type and get all types of compression */	for (i = 0; i < entries; i++) {		/* We have to apply this decompression? */		if (fDecompressions1 & dcmp_table[i].mask) {			count++;		}		/* Clear this flag from temporary variable. */		fDecompressions2 &= ~dcmp_table[i].mask;	}	/*	 *  Check if there is some method unhandled	 *  (E.g. compressed by future versions)	 */	if (fDecompressions2 != 0) {		printf("Unknown Compression\n");		return 0;	}	/* If there is more than only one compression, we have to allocate extra buffer */	if (count >= 2) {		temp_buf = (char*)malloc(out_length);	}	/* Apply all decompressions */	for (i = 0, count = 0; i < entries; i++) {		/* If not used this kind of compression, skip the loop */		if (fDecompressions1 & dcmp_table[i].mask) {			/* If odd case, use target buffer for output, otherwise use allocated tempbuf */			work_buf = (count++ & 1) ? temp_buf : out_buf;			out_length = *pout_length;			/* Decompress buffer using corresponding function */			dcmp_table[i].decompress(work_buf, &out_length, in_buf, in_length);			/* Move output length to src length for next compression */			in_length = out_length;			in_buf = work_buf;		}	}	/* If output buffer is not the same like target buffer, we have to copy data */	if (work_buf != out_buf) {		memcpy(out_buf, in_buf, out_length);	}	*pout_length = out_length;	/* Delete temporary buffer, if necessary */	if (temp_buf != NULL) {		free(temp_buf);	}	return 1;}

⌨️ 快捷键说明

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