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

📄 406-456.html

📁 The primary purpose of this book is to explain various data-compression techniques using the C progr
💻 HTML
📖 第 1 页 / 共 5 页
字号:
<!DOCTYPE HTML PUBLIC "html.dtd"><HTML><HEAD><TITLE>The Data Compression Book-:An Archiving Package</TITLE><META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW"><SCRIPT><!--function displayWindow(url, width, height) {        var Win = window.open(url,"displayWindow",'width=' + width +',height=' + height + ',resizable=1,scrollbars=yes');}//--></SCRIPT></HEAD><BODY  BGCOLOR="#FFFFFF" VLINK="#DD0000" TEXT="#000000" LINK="#DD0000" ALINK="#FF0000"><TD WIDTH="540" VALIGN="TOP"><!--  <CENTER><TABLE><TR><TD><FORM METHOD="GET" ACTION="http://search.itknowledge.com/excite/cgi-bin/AT-foldocsearch.cgi"><INPUT NAME="search" SIZE="20" VALUE=""><BR><CENTER><INPUT NAME="searchButton" TYPE="submit" VALUE="Glossary Search"></CENTER><INPUT NAME="source" TYPE="hidden" VALUE="local" CHECKED> <INPUT NAME="bltext" TYPE="hidden" VALUE="Back to Search"><INPUT NAME="sp" TYPE="hidden" VALUE="sp"></FORM></TD><TD><IMG SRC="http://www.itknowledge.com/images/dotclear.gif" WIDTH="15"   HEIGHT="1"></TD><TD><FORM METHOD="POST" ACTION="http://search.itknowledge.com/excite/cgi-bin/AT-subscriptionsearch.cgi"><INPUT NAME="search" SIZE="20" VALUE=""><BR><CENTER><INPUT NAME="searchButton" TYPE="submit" VALUE="  Book Search  "></CENTER><INPUT NAME="source" TYPE="hidden" VALUE="local" CHECKED> <INPUT NAME="backlink" TYPE="hidden" VALUE="http://search.itknowledge.com:80/excite/AT-subscriptionquery.html"><INPUT NAME="bltext" TYPE="hidden" VALUE="Back to Search"><INPUT NAME="sp" TYPE="hidden" VALUE="sp"></FORM></TD></TR></TABLE></CENTER> --><!-- ISBN=1558514341//--><!-- TITLE=The Data Compression Book-//--><!-- AUTHOR=Mark Nelson//--><!-- PUBLISHER=IDG Books Worldwide, Inc.//--><!-- IMPRINT=M & T Books//--><!-- CHAPTER=12//--><!-- PAGES=406-456//--><!-- UNASSIGNED1//--><!-- UNASSIGNED2//--><CENTER><TABLE BORDER><TR><TD><A HREF="403-406.html">Previous</A></TD><TD><A HREF="../ewtoc.html">Table of Contents</A></TD><TD><A HREF="../ch13/457-459.html">Next</A></TD></TR></TABLE></CENTER><P><BR></P><H4 ALIGN="LEFT"><A NAME="Heading14"></A><FONT COLOR="#000077">File Extraction</FONT></H4><P>The extraction routine in some ways is simpler than the Insert() routine. It doesn&#146;t have to deal with the possibility that the LZSS compression routine failed to compress. Instead, it just calls the appropriate routine based on the compression method stored in the header file. However, it does have a few extra jobs to deal with.</P><P>First of all, Extract can be called with a predefined destination FILE pointer. This occurs when the Print or Test commands are being executed. Print just extracts to stdout, and Test extracts to the null device, or the &#147;bit bucket&#148;. When this is the case, Extract() doesn&#146;t have to open a file to store the output.</P><P>In the case where Extract() is being called based on the Xtract command, it has to open the output file, check to make sure that goes okay, then close the file after the expansion takes place.</P><P>In all cases, Extract() has to check the CRC of the output file after the expansion routine has completed. When using the Test command, this is the way CARMAN verifies the integrity of the CAR file.</P><!--  CODE //--><PRE>void Extract( destination )FILE *destination;{ FILE *output_text_file; unsigned long crc;  int error;  fprintf( stderr, "%-20s ", Header.file_name );  error = 0;  if ( destination == NULL ) {   if ( ( output_text_file = fopen(Header.file_name, "wb")                            ) == NULL ) {    fprintf( stderr, "Can't open %s\n", Header.file_name );    fprintf( stderr, "Not extracted\n" );    SkipOverFileFromInputCar();    return;   }  } else   output_text_file = destination;  switch( Header.compression_method ) {   case 1 :    crc = Unstore( output_text_file );    break;   case 2 :    crc = LZSSExpand( output_text_file );    break;   default :    fprintf( stderr, "Unknown method: %c\n",         Header.compression_method );    SkipOverFileFromInputCar();    error = 1;    crc = Header.original_crc;    break;  }  if ( crc != Header.original_crc ) {    fprintf( stderr, "CRC error reading data\n" );    error = 1;  }  if ( destination == NULL ) {   fclose( output_text_file );   if ( error )  #ifdef __STDC__        remove( Header.file_name );  #else        unlink( Header.file_name );  #endif  }  if ( !error )   fprintf (stderr, " OK\n" );}</PRE><!--  END CODE //--><H4 ALIGN="LEFT"><A NAME="Heading15"></A><FONT COLOR="#000077">Cleanup</FONT></H4><P>The final job left to CARMAN after making its way through the main processing loop is to clean up the workspace used by the program. The first step is to write out the special EOF header to the output CAR file. This is done using a dedicated routine called WriteEndOfCarHeader(), which simply writes a zero length file name to the header file.</P><P>Next, the output CAR file is closed and checked for errors. At this point, the output CAR file has been completely processed and is ready to replace the input file. In order to do this, the input file is deleted, and the output file is renamed to have the original archive name. This takes slightly different code under UNIX than MS-DOS, but it is relatively straightforward.</P><H3><A NAME="Heading16"></A><FONT COLOR="#000077">The Code</FONT></H3><P>A complete listing of the CARMAN program follows, including sections that have only been lightly touched on in this chapter. The LZSS compression code is nearly identical to that shown earlier in Chapter 8, with a slightly modified I/O system.</P><P>Programmers wishing to compile this under MS-DOS are advised to pay close attention to those portions of the code that are surrounded by #ifdef MSDOS sections. These portions may need slight modifications to work with different MSDOS compilers, but the modifications should only consist of renamed functions and structures. The actual flow of control inside the program should be identical.</P><!--  CODE //--><PRE>/**************************** Start of CARMAN.C *************************** This is the main program for the simple Compressed Archive Manager.* This program can be used to add, delete, extract, or list the files* in a CAR archive. The code here should run under standard ANSI* compilers under MS-DOS (with ANSI mode selected) or K&#38;R compilers* under UNIX. The code uses an LZSS compression algorithm identical to* that used earlier in the book.*/#include &lt;stdio.h&gt;#include &lt;stdlib.h&gt;#include &lt;string.h&gt;#include &lt;ctype.h&gt;#ifdef __STDC__#include &lt;stdarg.h&gt;#else#include &lt;varargs.h&gt;#endif#ifdef __STDC__ /* All Borland C/C++ versions */ #ifdef __TURBOC__   #define MSDOS 1   #include &lt;io.h&gt;   #include &lt;dir.h&gt;   #define DIR_STRUCT struct ffblk   #define FIND_FIRST(n, d, a ) findfirst( n, d, a )   #define FIND_NEXT findnext   #define DIR_FILE_NAME ff_name#endif /*Microsoft, Watcom, Zortech */#if defined( M__186 ) || defined ( __ZTC__ ) || defined ( __TSC__ ) #define MSDOS 1 #include &lt;dos.h&gt; #define DIR_STRUCT struct find_t #define FIND_FIRST( n, d, a) _dos_findfirst( n, a, d ) #define FIND_NEXT _dos_findnext #define DIR_FILE_NAME name #endif#endif/** A few constants used throughout the program.*/#define BASE_HEADER_SIZE 19#define CRC_MASK 0xFFFFFFFFL#define CRC32_POLYNOMIAL 0xEDB88320L/** The only data structure used inside the CAR file is the header block.* Each file is preceded by a header, stored in a portable format.* The header is read into and out of the structure defined below.* The CAR file is structured as a series of header/data sequences, with* the EOF being denoted as a header with a file name length of 0. Note* that the length of each header will vary depending on the length of* the file name.*/#ifndef FILENAME_MAX#define FILENAME_MAX 128#endiftypedef struct header { char file_name[ FILENAME_MAX ]; char compression_method; unsigned long original_size; unsigned long compressed_size; unsigned long original_crc; unsigned long header_crc;} HEADER;/** Local function prototypes*/#ifdef __STDC__void FatalError( char *message, ... );void BuildCRCTable( void );unsigned long CalculateBlockCRC32( unsigned int count, unsigned long crc,                          void *buffer );unsigned long UpdateCharacterCRC32( unsigned long crc, int c );int ParseArguments( int argc, char *argv[] );void UsageExit( void );void OpenArchiveFiles( char *name, int command );void BuildFileList( int argc, char *argv[], int command );int ExpandAndMassageMSDOSFileNames( int count, char *wild_name );void MassageMSDOSFileName( int count, char *file );int AddFileListToArchive( void );int ProcessAllFilesInInputCar( int command, int count );int SearchFileList( char *file_name );int WildCardMatch( char *s1, char *s2 );void SkipOverFileFromInputCar( void );void CopyFileFromInputCar( void );void PrintListTitles( void );void ListCarFileEntry( void );int RatioInPercent( unsigned long compressed, unsigned long original );int ReadFileHeader( void );unsigned long UnpackUnsignedData( int number_of_bytes,                      unsigned char *buffer );void WriteFileHeader( void );void PackUnsignedData( int number_of_bytes, unsigned long number,                      unsigned char *buffer );void WriteEndOfCarHeader( void );void Insert( FILE *input_text_file, char *operation );void Extract( FILE *destination );int Store( FILE *input_text_file );unsigned long Unstore( FILE *destination );int LZSSCompress( FILE *input_text_file );unsigned long LZSSExpand( FILE *destination );#elsevoid FatalError();void BuildCRCTable();unsigned long CalculateBlockCRC32();unsigned long UpdateCharacterCRC32();int ParseArguments();void UsageExit();void OpenArchiveFiles();void BuildFileList();int ExpandAndMassageMSDOSFileNames();void MassageMSDOSFileName();int AddFileListToArchive();int ProcessAllFilesInInputCar();int SearchFileList();int WildCardMatch();void SkipOverFileFromInputCar();void CopyFileFromInputCar();void PrintListTitles();void ListCarFileEntry();int RatioInPercent();int ReadFileHeader();unsigned long UnpackUnsignedData();void WriteFileHeader();void PackUnsignedData();void WriteEndOfCarHeader();void Insert();void Extract();int Store();unsigned long Unstore();int LZSSCompress();unsigned long LZSSExpand();#endif/** All global variables are defined here.*/char *TempFileName[ FILENAME_MAX ]; /* The output archive is first    */                                    /* opened with a temporary name   */FILE * InputCarFile;                /* The input CAR file. This file  */                                    /* may not exist for 'A' commands */char CarFileName[ FILENAME_MAX ];   /* Name of the CAR file, defined  */                                    /* on the command line            */FILE *OutputCarFile;                /* The output CAR, only exists for*/                                    /* the 'A' and 'R' operations     */HEADER Header;                      /* The Header block for the file  */                                    /* presently being operated on    */char *FileList[ 100 ];              /* The list of file names passed  */                                    /* on the command line            */unsigned long Ccitt32Table[ 256 ];  /* This array holds the CRC       */                                    /* table used to calculate the 32 */                                    /* bit CRC values                 *//** This is the main routine for processing CAR commands. Most of the* major work involved here has been delegated to other functions.* This routine first parses the command line, then opens up the input* and possibly the output archive. It then builds a list of files* to be processed by the current command. If the command was 'A', all* of the files are immediately added to the output archives. Finally,* the main processing loop is called. It scans through the entire* archive, taking action on each file as necessary. Once that is* complete, all that is left to do is optionally delete the input file,* then rename the output file to have the correct CAR file name.*/int main( argc, argv )int argc;char *argv[];{ int command; int count; setbuf( stdout, NULL ); setbuf( stderr, NULL ): fprintf( stderr, "CARMAN 1.0 : " ); BuildCRCTable(); command = ParseArguments( argc, argv ); fprintf( stderr, "\n" ); OpenArchiveFiles( argv[ 2 ], command ); BuildFileList( argc - 3, argv + 3, command ); if ( command == 'A' )  count = AddFileListToArchive(); else  count = 0; if ( command == 'L' )  PrintListTitles(); count = ProcessAllFilesInInputCar( command, count ); if ( OutputCarFile != NULL &#38;&#38; count != 0 ) {  WriteEndOfCarHeader();  if ( ferror( OutputCarFile ) || fclose( OutputCarFile ) == EOF )   FatalError( "Can't write" );  #ifdef __STDC__   remove( CarFileName );   rename(TempFileName, CarFileName );  #else   unlink( CarFileName );   link( TempFileName, CarFileName );   unlink( TempFileName );  #endif } if ( command != 'P' )  printf( "\n%d file%s\n", count, ( count == 1 ) ? "" : "s" );  else  fprintf( stderr, "\n%d file%s\n", count,                 ( count == 1 ) ? '' : "s" );  return( 0 );}/** FatalError provides a short way for us to exit the program when* something bad happens, as well as printing a diagnostic message.* If an output CAR file has been opened, it is deleted as well,* which cleans up most of the traces of our work here. Note that* K&#38;R compilers handle variable length argument lists differently* than ANSI compilers, so we have two different entries for the* routines.*/#ifdef __STDC__void FatalError( char *fmt, ... ){ va_list args; va_start( args, fmt );#elsevoid FatalError( va_alist )va_dcl{ va_list args; char *fmt; va_start( args ); fmt = va_arg( args, char * );

⌨️ 快捷键说明

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