bunzip2.c

来自「这是一个SIGMA方案的PMP播放器的UCLINUX程序,可播放DVD,VCD,」· C语言 代码 · 共 1,866 行 · 第 1/3 页

C
1,866
字号
		case BZ_X_CCRC_3:			s->state = BZ_X_CCRC_3;			if (! get_bits(s, &uc, 8)) {				retVal = BZ_OK;				goto save_state_and_return;			}			s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((unsigned int)uc);		case BZ_X_CCRC_4:			s->state = BZ_X_CCRC_4;			if (! get_bits(s, &uc, 8)) {				retVal = BZ_OK;				goto save_state_and_return;			}			s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((unsigned int)uc);		s->state = BZ_X_IDLE;		retVal = BZ_STREAM_END;		goto save_state_and_return;	}save_state_and_return:	s->save_i           = i;	s->save_j           = j;	s->save_t           = t;	s->save_alphaSize   = alphaSize;	s->save_nGroups     = nGroups;	s->save_nSelectors  = nSelectors;	s->save_EOB         = EOB;	s->save_groupNo     = groupNo;	s->save_groupPos    = groupPos;	s->save_nextSym     = nextSym;	s->save_nblockMAX   = nblockMAX;	s->save_nblock      = nblock;	s->save_es          = es;	s->save_N           = N;	s->save_curr        = curr;	s->save_zt          = zt;	s->save_zn          = zn;	s->save_zvec        = zvec;	s->save_zj          = zj;	s->save_gSel        = gSel;	s->save_gMinlen     = gMinlen;	s->save_gLimit      = gLimit;	s->save_gBase       = gBase;	s->save_gPerm       = gPerm;	return retVal;   }//int BZ2_bzDecompressInit(bz_stream* strm, int verbosity_level, int small)static inline int BZ2_bzDecompressInit(bz_stream* strm){	DState* s;//	if (verbosity_level < 0 || verbosity_level > 4) {//		return BZ_PARAM_ERROR;//	}	s = xmalloc(sizeof(DState));	s->strm                  = strm;	strm->state              = s;	s->state                 = BZ_X_MAGIC_1;	s->bsLive                = 0;	s->bsBuff                = 0;	s->calculatedCombinedCRC = 0;	s->tt                    = NULL;	s->currBlockNo           = 0;	return BZ_OK;}static void bz_seterr(int eee, int *bzerror, bzFile **bzf){	if (bzerror != NULL) {		*bzerror = eee;	}	if (*bzf != NULL) {		(*bzf)->lastErr = eee;	}}static void BZ2_bzReadClose(int *bzerror, void *b){	bzFile* bzf = (bzFile*)b;	bz_seterr(BZ_OK, bzerror, &bzf);	if (bzf->initialisedOk) {		bz_stream *strm = &(bzf->strm);		DState *s;		if (strm == NULL) {			return;		}		s = strm->state;		if ((s == NULL) || (s->strm != strm)) {			return;		}		free(s->tt);		free(strm->state);		strm->state = NULL;		return;	}	free(bzf);}static void unRLE_obuf_to_output_FAST(DState *s){	unsigned char k1;	if (s->blockRandomised) {		while (1) {			/* try to finish existing run */			while (1) {				if (s->strm->avail_out == 0) {					return;				}				if (s->state_out_len == 0) {					break;				}				*((unsigned char *)(s->strm->next_out)) = s->state_out_ch;				s->calculatedBlockCRC = (s->calculatedBlockCRC << 8) ^					BZ2_crc32Table[(s->calculatedBlockCRC >> 24) ^					((unsigned char)s->state_out_ch)];				s->state_out_len--;				s->strm->next_out++;				s->strm->avail_out--;			}   			/* can a new run be started? */			if (s->nblock_used == s->save_nblock+1) {				return;			}			s->state_out_len = 1;			s->state_out_ch = s->k0;			k1 = bz_get_fast(s);			bz_rand_udp_mask(s);			k1 ^= ((s->rNToGo == 1) ? 1 : 0);			s->nblock_used++;			if (s->nblock_used == s->save_nblock+1) {				continue;			}			if (k1 != s->k0) {				s->k0 = k1;				continue;			}			s->state_out_len = 2;			k1 = bz_get_fast(s);			bz_rand_udp_mask(s);			k1 ^= ((s->rNToGo == 1) ? 1 : 0);			s->nblock_used++;			if (s->nblock_used == s->save_nblock+1) {				continue;			}			if (k1 != s->k0) {				s->k0 = k1;				continue;			}			s->state_out_len = 3;			k1 = bz_get_fast(s);			bz_rand_udp_mask(s);			k1 ^= ((s->rNToGo == 1) ? 1 : 0);			s->nblock_used++;			if (s->nblock_used == s->save_nblock+1) {				continue;			}			if (k1 != s->k0) {				s->k0 = k1;				continue;			}			k1 = bz_get_fast(s);			bz_rand_udp_mask(s);			k1 ^= ((s->rNToGo == 1) ? 1 : 0);			s->nblock_used++;			s->state_out_len = ((int)k1) + 4;			s->k0 = bz_get_fast(s);			bz_rand_udp_mask(s);			s->k0 ^= ((s->rNToGo == 1) ? 1 : 0);			s->nblock_used++;		}	} else {		/* restore */		unsigned int c_calculatedBlockCRC = s->calculatedBlockCRC;		unsigned char c_state_out_ch       = s->state_out_ch;		int c_state_out_len      = s->state_out_len;		int c_nblock_used        = s->nblock_used;		int c_k0                 = s->k0;		unsigned int	*c_tt                 = s->tt;		unsigned int	c_tPos               = s->tPos;		char	*cs_next_out          = s->strm->next_out;		unsigned int  cs_avail_out         = s->strm->avail_out;		/* end restore */		int        s_save_nblockPP = s->save_nblock+1;		while (1) {			/* try to finish existing run */			if (c_state_out_len > 0) {				while (TRUE) {					if (cs_avail_out == 0) {						goto return_notr;					}					if (c_state_out_len == 1) {						break;					}					*((unsigned char *)(cs_next_out)) = c_state_out_ch;					c_calculatedBlockCRC = (c_calculatedBlockCRC << 8) ^						BZ2_crc32Table[(c_calculatedBlockCRC >> 24) ^						((unsigned char)c_state_out_ch)];					c_state_out_len--;					cs_next_out++;					cs_avail_out--;				}s_state_out_len_eq_one:				{					if (cs_avail_out == 0) { 						c_state_out_len = 1;						goto return_notr;					}					*((unsigned char *)(cs_next_out)) = c_state_out_ch;					c_calculatedBlockCRC = (c_calculatedBlockCRC << 8) ^						BZ2_crc32Table[(c_calculatedBlockCRC >> 24) ^						((unsigned char)c_state_out_ch)];					cs_next_out++;					cs_avail_out--;				}			}   			/* can a new run be started? */			if (c_nblock_used == s_save_nblockPP) {				c_state_out_len = 0; goto return_notr;			}			c_state_out_ch = c_k0;			c_tPos = c_tt[c_tPos];			k1 = (unsigned char)(c_tPos & 0xff);			c_tPos >>= 8;			c_nblock_used++;			if (k1 != c_k0) { 				c_k0 = k1;				goto s_state_out_len_eq_one; 			}			if (c_nblock_used == s_save_nblockPP) {				goto s_state_out_len_eq_one;			}			c_state_out_len = 2;			c_tPos = c_tt[c_tPos];			k1 = (unsigned char)(c_tPos & 0xff);			c_tPos >>= 8;			c_nblock_used++;			if (c_nblock_used == s_save_nblockPP) {				continue;			}			if (k1 != c_k0) {				c_k0 = k1;				continue;			}			c_state_out_len = 3;			c_tPos = c_tt[c_tPos];			k1 = (unsigned char)(c_tPos & 0xff);			c_tPos >>= 8;			c_nblock_used++;			if (c_nblock_used == s_save_nblockPP) {				continue;			}			if (k1 != c_k0) {				c_k0 = k1;				continue;			}   			c_tPos = c_tt[c_tPos];			k1 = (unsigned char)(c_tPos & 0xff);			c_tPos >>= 8;			c_nblock_used++;			c_state_out_len = ((int)k1) + 4;			c_tPos = c_tt[c_tPos];			c_k0 = (unsigned char)(c_tPos & 0xff);			c_tPos >>= 8;			c_nblock_used++;		}return_notr:		/* save */		s->calculatedBlockCRC = c_calculatedBlockCRC;		s->state_out_ch       = c_state_out_ch;		s->state_out_len      = c_state_out_len;		s->nblock_used        = c_nblock_used;		s->k0                 = c_k0;		s->tt                 = c_tt;		s->tPos               = c_tPos;		s->strm->next_out     = cs_next_out;		s->strm->avail_out    = cs_avail_out;		/* end save */	}}static inlineint BZ2_bzDecompress(bz_stream *strm){	DState* s;	s = strm->state;	while (1) {		if (s->state == BZ_X_IDLE) {			return BZ_SEQUENCE_ERROR;		}		if (s->state == BZ_X_OUTPUT) {			unRLE_obuf_to_output_FAST(s);			if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {				s->calculatedBlockCRC = ~(s->calculatedBlockCRC);				if (s->calculatedBlockCRC != s->storedBlockCRC) {					return BZ_DATA_ERROR;				}				s->calculatedCombinedCRC = (s->calculatedCombinedCRC << 1) | (s->calculatedCombinedCRC >> 31);				s->calculatedCombinedCRC ^= s->calculatedBlockCRC;				s->state = BZ_X_BLKHDR_1;			} else {				return BZ_OK;			}		}		if (s->state >= BZ_X_MAGIC_1) {			int r = BZ2_decompress(s);			if (r == BZ_STREAM_END) {				if (s->calculatedCombinedCRC != s->storedCombinedCRC) {					return BZ_DATA_ERROR;				}				return r;			}			if (s->state != BZ_X_OUTPUT) {				return r;			}		}	}	return(0);  /*NOTREACHED*/}static inline int BZ2_bzRead(int *bzerror, void *b, void *buf, int len){	int n, ret;	bzFile *bzf = (bzFile*)b;	bz_seterr(BZ_OK, bzerror, &bzf);	if (len == 0) {		bz_seterr(BZ_OK, bzerror, &bzf);		return 0;	}	bzf->strm.avail_out = len;	bzf->strm.next_out = buf;	while (1) {		if (ferror(bzf->handle)) {			bz_seterr(BZ_IO_ERROR, bzerror, &bzf);			return 0;		}		if ((bzf->strm.avail_in == 0) && !myfeof(bzf->handle)) {			n = fread(bzf->buf, sizeof(unsigned char), BZ_MAX_UNUSED, bzf->handle);			if (ferror(bzf->handle)) {				bz_seterr(BZ_IO_ERROR, bzerror, &bzf);				return 0;			}			bzf->bufN = n;			bzf->strm.avail_in = bzf->bufN;			bzf->strm.next_in = bzf->buf;		}		ret = BZ2_bzDecompress(&(bzf->strm));		if ((ret != BZ_OK) && (ret != BZ_STREAM_END)) {			bz_seterr(ret, bzerror, &bzf);			return 0;		}		if ((ret == BZ_OK) && myfeof(bzf->handle) &&			(bzf->strm.avail_in == 0) && (bzf->strm.avail_out > 0)) {			bz_seterr(BZ_UNEXPECTED_EOF, bzerror, &bzf);			return(0);		}		if (ret == BZ_STREAM_END) {			bz_seterr(BZ_STREAM_END, bzerror, &bzf);			return(len - bzf->strm.avail_out);		}		if (bzf->strm.avail_out == 0) {			bz_seterr(BZ_OK, bzerror, &bzf);			return(len);		}	}	return(0); /*not reached*/}static inline void *BZ2_bzReadOpen(int *bzerror, FILE *f, void *unused, int nUnused){	bzFile *bzf = xmalloc(sizeof(bzFile));	int ret;	bz_seterr(BZ_OK, bzerror, &bzf);	bzf->initialisedOk = FALSE;	bzf->handle        = f;	bzf->bufN          = 0;	ret = BZ2_bzDecompressInit(&(bzf->strm));	if (ret != BZ_OK) {		bz_seterr(ret, bzerror, &bzf);		free(bzf);		return NULL;	}	while (nUnused > 0) {		bzf->buf[bzf->bufN] = *((unsigned char *)(unused)); bzf->bufN++;		unused = ((void *)( 1 + ((unsigned char *)(unused))  ));		nUnused--;	}	bzf->strm.avail_in = bzf->bufN;	bzf->strm.next_in  = bzf->buf;	bzf->initialisedOk = TRUE;	return bzf;   }static inline unsigned char uncompressStream(FILE *zStream, FILE *stream){	unsigned char unused[BZ_MAX_UNUSED];	unsigned char *unusedTmp;	unsigned char obuf[5000];	bzFile *bzf = NULL;	int bzerr_dummy;	int bzerr;	int nread;	int nUnused;	int streamNo;	int ret;	int i;	nUnused = 0;	streamNo = 0;	if (ferror(stream)) {		goto errhandler_io;	}	if (ferror(zStream)) {		goto errhandler_io;	}	while(1) {		bzf = BZ2_bzReadOpen(&bzerr, zStream, unused, nUnused);		if (bzf == NULL || bzerr != BZ_OK) {			goto errhandler;		}		streamNo++;		while (bzerr == BZ_OK) {			nread = BZ2_bzRead(&bzerr, bzf, obuf, 5000);			if (bzerr == BZ_DATA_ERROR_MAGIC) {				goto errhandler;			}			if ((bzerr == BZ_OK || bzerr == BZ_STREAM_END) && nread > 0) {				fwrite(obuf, sizeof(unsigned char), nread, stream);			}			if (ferror(stream)) {				goto errhandler_io;			}		}		if (bzerr != BZ_STREAM_END) {			goto errhandler;		}		nUnused = bzf->strm.avail_in;		unusedTmp = bzf->strm.next_in;		bz_seterr(BZ_OK, &bzerr, &bzf);		for (i = 0; i < nUnused; i++) {			unused[i] = unusedTmp[i];		}		BZ2_bzReadClose(&bzerr, bzf);		if ((nUnused == 0) && myfeof(zStream)) {			break;		}	}	if (ferror(zStream)) {		goto errhandler_io;	}	ret = fclose(zStream);	if (ret == EOF) {		goto errhandler_io;	}	if (ferror(stream)) {		goto errhandler_io;	}	ret = fflush(stream);	if (ret != 0) {		goto errhandler_io;	}	if (stream != stdout) {		ret = fclose(stream);		if (ret == EOF) {			goto errhandler_io;		}	}	return TRUE;errhandler:	BZ2_bzReadClose ( &bzerr_dummy, bzf );	switch (bzerr) {		case BZ_IO_ERROR:errhandler_io:			error_msg("\n%s: I/O or other error, bailing out.  "				"Possible reason follows.\n", applet_name);			perror(applet_name);			exit(1);		case BZ_DATA_ERROR:			error_msg("\n%s: Data integrity error when decompressing.\n", applet_name);			exit(2);		case BZ_UNEXPECTED_EOF:			error_msg("\n%s: Compressed file ends unexpectedly;\n\t"				"perhaps it is corrupted?  *Possible* reason follows.\n", applet_name);			perror(applet_name);			exit(2);		case BZ_DATA_ERROR_MAGIC:			if (zStream != stdin) {				fclose(zStream);			}			if (stream != stdout) {				fclose(stream);			}			if (streamNo == 1) {				return FALSE;			} else {				return TRUE;			}	}	return(TRUE); /*notreached*/}int bunzip2_main(int argc, char **argv){	const int bunzip_to_stdout = 1;	const int bunzip_force = 2;	int flags = 0;	int opt = 0;	int status;	FILE *src_stream;	FILE *dst_stream;	char *save_name = NULL;	char *delete_name = NULL;	/* if called as bzcat */	if (strcmp(applet_name, "bzcat") == 0)		flags |= bunzip_to_stdout;	while ((opt = getopt(argc, argv, "cfh")) != -1) {		switch (opt) {		case 'c':			flags |= bunzip_to_stdout;			break;		case 'f':			flags |= bunzip_force;			break;		case 'h':		default:			show_usage(); /* exit's inside usage */		}	}	/* Set input filename and number */	if (argv[optind] == NULL || strcmp(argv[optind], "-") == 0) {		flags |= bunzip_to_stdout;		src_stream = stdin;	} else {		/* Open input file */		src_stream = xfopen(argv[optind], "r");		save_name = xstrdup(argv[optind]);		if (strcmp(save_name + strlen(save_name) - 4, ".bz2") != 0)			error_msg_and_die("Invalid extension");		save_name[strlen(save_name) - 4] = '\0';	}	/* Check that the input is sane.  */	if (isatty(fileno(src_stream)) && (flags & bunzip_force) == 0)		error_msg_and_die("compressed data not read from terminal.  Use -f to force it.");	if (flags & bunzip_to_stdout) {		dst_stream = stdout;	} else {		dst_stream = xfopen(save_name, "w");	}	if (uncompressStream(src_stream, dst_stream)) {		if (!(flags & bunzip_to_stdout))			delete_name = argv[optind];		status = EXIT_SUCCESS;	} else {		if (!(flags & bunzip_to_stdout))			delete_name = save_name;		status = EXIT_FAILURE;	}	if (delete_name) {		if (unlink(delete_name) < 0) {			error_msg_and_die("Couldn't remove %s", delete_name);		}	}	return status;}

⌨️ 快捷键说明

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