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

📄 mscompress.c

📁 压缩小工具,其中有压缩原代码请大家多指教
💻 C
字号:
/* *  mscompress: Microsoft "compress.exe/expand.exe" compatible compressor * *  Copyright (c) 2000 Martin Hinner <mhi@penguin.cz> *  Algorithm & data structures by M. Winterhoff <100326.2776@compuserve.com> * *  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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */#include "config.h"#include <stdio.h>#include <stdlib.h>#include <sys/stat.h>#include <unistd.h>#include <fcntl.h>#include <string.h>#ifdef HAVE_GETOPT_H#include <getopt.h>#else#include "getopt.h"#endifextern char *version_string;#define BSWAP32(x)             ((((x)&0xFF)<<24)+(((x)<<8)&0xFF0000)+\			        (((x)>>8)&0xFF00)+(((x)>>24)&0xFF))#define N 4096#define F 16#define THRESHOLD 3#define dad (node+1)#define lson (node+1+N)#define rson (node+1+N+N)#define root (node+1+N+N+N)#define NIL -1char *buffer;int *node;int pos;#define max(x,y) ((x)>(y)?(x):(y))#define min(x,y) ((y)>(x)?(x):(y))intinsert (int i, int run){  int c, j, k, l, n, match;  int *p;  k = l = 1;  match = THRESHOLD - 1;  p = &root[(unsigned char) buffer[i]];  lson[i] = rson[i] = NIL;  while ((j = *p) != NIL)    {      n = min (k, l);      while (n < run && (c = (buffer[j + n] - buffer[i + n])) == 0)	n++;      if (n > match)	{	  match = n;	  pos = j;	}      if (c < 0)	{	  p = &lson[j];	  k = n;	}      else if (c > 0)	{	  p = &rson[j];	  l = n;	}      else	{	  dad[j] = NIL;	  dad[lson[j]] = lson + i - node;	  dad[rson[j]] = rson + i - node;	  lson[i] = lson[j];	  rson[i] = rson[j];	  break;	}    }  dad[i] = p - node;  *p = i;  return match;}voiddelete (int z){  int j;  if (dad[z] != NIL)    {      if (rson[z] == NIL)	{	  j = lson[z];	}      else if (lson[z] == NIL)	{	  j = rson[z];	}      else	{	  j = lson[z];	  if (rson[j] != NIL)	    {	      do		{		  j = rson[j];		}	      while (rson[j] != NIL);	      node[dad[j]] = lson[j];	      dad[lson[j]] = dad[j];	      lson[j] = lson[z];	      dad[lson[z]] = lson + j - node;	    }	  rson[j] = rson[z];	  dad[rson[z]] = rson + j - node;	}      dad[j] = dad[z];      node[dad[z]] = j;      dad[z] = NIL;    }}intgetbyte (int f){  unsigned char b;  /* Is there a better way?  */  if (read (f, &b, sizeof (b)) != 1)    return -1;  return b;}intcompress (int in, char *inname, int out, char *outname){  int ch, i, run, len, match, size, mask;  char buf[17];  struct stat st;  unsigned long magic1;  unsigned long magic2;  unsigned short magic3;  unsigned long filesize;  /* 28.5 kB */  buffer = malloc (N + F + (N + 1 + N + N + 256) * sizeof (int));  if (!buffer)    {      fprintf (stderr, "%s: Not enough memory!\n", inname);      return -1;    }  if (fstat (in, &st) < 0)    {      perror (inname);      return -1;    }  /* Fill in header */#ifdef WORDS_BIGENDIAN		/* Sparc, MC68000, PPC, ... */  magic1 = 0x535A4444;		/* SZDD */  magic2 = 0x88f02733;  magic3 = 0x4100;  filesize = BSWAP32 (st.st_size);#else				/* Intel, VAX, ... */  magic1 = 0x44445A53L;		/* SZDD */  magic2 = 0x3327F088L;  magic3 = 0x0041;  filesize = st.st_size;#endif  /* Write header to the output file */  if (write (out, &magic1, sizeof (magic1)) != sizeof (magic1))    {      perror (outname);      free (buffer);      return -1;    }  if (write (out, &magic2, sizeof (magic2)) != sizeof (magic2))    {      perror (outname);      free (buffer);      return -1;    }  if (write (out, &magic3, sizeof (magic3)) != sizeof (magic3))    {      perror (outname);      free (buffer);      return -1;    }  if (write (out, &filesize, sizeof (filesize)) != sizeof (filesize))    {      perror (outname);      free (buffer);      return -1;    }  node = (int *) (buffer + N + F);  for (i = 0; i < 256; i++)    root[i] = NIL;  for (i = NIL; i < N; i++)    dad[i] = NIL;  size = mask = 1;  buf[0] = 0;  i = N - F - F;  for (len = 0; len < F && (ch = getbyte (in)) != -1; len++)    {      buffer[i + F] = ch;      i = (i + 1) % N;    }  run = len;  do    {      ch = getbyte (in);      if (i >= N - F)	{	  delete (i + F - N);	  buffer[i + F] = buffer[i + F - N] = ch;	}      else	{	  delete (i + F);	  buffer[i + F] = ch;	}      match = insert (i, run);      if (ch == -1)	{	  run--;	  len--;	}      if (len++ >= run)	{	  if (match >= THRESHOLD)	    {//printf("%u{%u,%u}",size,pos, match-3);	      buf[size++] = pos;	      buf[size++] = ((pos >> 4) & 0xF0) + (match - 3);	      len -= match;	    }	  else	    {	      buf[0] |= mask;//printf("%u[%c]",size,buffer[i]);	      buf[size++] = buffer[i];	      len--;	    }	  if (!((mask += mask) & 0xFF))	    {	      if (write (out, buf, size) != size)		{		  perror (outname);		  free (buffer);		  return -1;		}	      size = mask = 1;	      buf[0] = 0;	    }	}      i = (i + 1) & (N - 1);    }  while (len > 0);  if (size > 1)    if (write (out, buf, size) != size)      {	perror (outname);	free (buffer);	return -1;      }  free (buffer);  return 0;}voidusage (char *progname){  printf ("Usage: %s [-h] [-V] [file ...]\n"	  " -h --help        give this help\n"	  " -V --version     display version number\n"	  " file...          files to compress."	  "\n"	  "Report bugs to <mhi@penguin.cz>\n", progname);  exit (0);}voidmain (int argc, char **argv){  int in, out;  char *argv0;  char c;  char name[0x100];  argv0 = argv[0];  while ((c = getopt (argc, argv, "hV")) != -1)    {      switch (c)	{	case 'h':	  usage (argv0);	case 'V':	  printf ("mscompress version %s (" BUILDHOST ") "__DATE__ " \n",			version_string);	  exit (0);	default:	  usage (argv0);	}    }  argc -= optind;  argv += optind;  if (argc == 0)    {      fprintf (stderr, "%s: No files specified\n", argv0);      usage (argv0);    }  while (argc)    {      if (argv[0][strlen (argv[0]) - 1] == '_')	{	  fprintf (stderr, "%s: Already ends with underscore -- ignored\n", argv[0]);	  argc--;	  argv++;	  continue;	}      in = open (argv[0], O_RDONLY);      if (in < 0)	{	  perror (argv[0]);	  exit (1);	}      strcpy (name, argv[0]);      strcat (name, "_");      out = open (name, O_WRONLY | O_CREAT | O_EXCL, 0644);      if (out < 0)	{	  perror (name);	  exit (1);	}      compress (in, argv[0], out, name);      close (in);      close (out);      argc--;      argv++;    }  exit (0);}

⌨️ 快捷键说明

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