home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / pslib / library.c < prev    next >
C/C++ Source or Header  |  1998-06-08  |  19KB  |  656 lines

  1. /*
  2. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  3. SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  4. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  5. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  6. IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  7. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  8. FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  9. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  10. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
  11. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  12. */
  13. /*
  14.  * $Source: f:/miner/source/pslib/rcs/library.c $
  15.  * $Revision: 1.30 $
  16.  * $Author: matt $
  17.  * $Date: 1994/03/23 13:55:30 $
  18.  *
  19.  * Sample setup for RCS header
  20.  *
  21.  * $Log: library.c $
  22.  * Revision 1.30  1994/03/23  13:55:30  matt
  23.  * Set others_use in library get info routine
  24.  * 
  25.  * Revision 1.29  1994/02/15  12:53:25  john
  26.  * Made numfiles stored in library be a short instead of char.
  27.  * 
  28.  * Revision 1.28  1994/02/14  20:11:38  john
  29.  * First version working with new cfile stuff.
  30.  * 
  31.  * Revision 1.27  1994/01/17  11:01:23  john
  32.  * Made cfopen return NULL when file not found instead
  33.  * of doing an Error inside ReadFile.
  34.  * 
  35.  * Revision 1.26  1994/01/07  12:02:41  yuan
  36.  * fixed problem with checkfile.
  37.  * CheckFile now checks the directory first, rather
  38.  * than the library
  39.  * 
  40.  * Revision 1.25  1994/01/07  11:45:24  yuan
  41.  * cleaned up some code.
  42.  * 
  43.  * Revision 1.24  1994/01/07  10:24:29  yuan
  44.  * Makes it so ReadFile reads from directory before
  45.  * it checks the library file.
  46.  * 
  47.  * Revision 1.23  1993/12/15  11:18:45  yuan
  48.  * Fixed calloc in lib_init... Changed it to MALLOC
  49.  * 
  50.  * Revision 1.22  1993/12/10  19:26:13  matt
  51.  * Made more functions call Error() instead of returning error codes
  52.  * 
  53.  * Revision 1.21  1993/12/08  17:06:47  yuan
  54.  * Added CheckFile();
  55.  * 
  56.  * Revision 1.20  1993/12/08  16:07:05  yuan
  57.  * Changed MAX_FILES for FileList[]
  58.  * 
  59.  * Revision 1.19  1993/10/28  14:40:55  yuan
  60.  * cfread changed to cfreadfile.
  61.  * 
  62.  * Revision 1.18  1993/10/27  12:42:29  yuan
  63.  * Added ReadFileBuf to read into a buffer (compressed)
  64.  * 
  65.  * Revision 1.17  1993/10/19  14:11:09  yuan
  66.  * Fixed uncompress reading/writing problem
  67.  * 
  68.  * Revision 1.16  1993/10/19  13:55:44  matt
  69.  * Made ReadFile() call Error() on file error
  70.  * 
  71.  * Revision 1.15  1993/10/19  12:38:53  matt
  72.  * Cleaned up error handling in lib_init() a little
  73.  * 
  74.  * Revision 1.14  1993/10/19  11:33:33  yuan
  75.  * Fixed cfread free problem.
  76.  * 
  77.  * Revision 1.13  1993/10/18  18:00:27  yuan
  78.  * Fixed memory alloc errors.
  79.  * 
  80.  * Revision 1.12  1993/10/17  18:01:48  yuan
  81.  * Fixed the first file counting problem.
  82.  * 
  83.  * Revision 1.11  1993/09/29  17:52:59  yuan
  84.  * *** empty log message ***
  85.  * 
  86.  * Revision 1.10  1993/09/29  17:46:54  yuan
  87.  * ReadFile, etc. I/O functions moved back into library.c
  88.  * ReadFile was renamed to ReadFileRaw which just reads
  89.  * a file into a buffer... LibReadFile was renamed to
  90.  * ReadFile, and it reads from either a library or a buffer
  91.  * depending on lib_init and if the file is found in the
  92.  * library.
  93.  * 
  94.  * Also, printfs and exits for errors were removed.
  95.  *
  96.  * In this version, ReadFile should be completely transparent
  97.  * to the user.
  98.  * 
  99.  * Revision 1.9  1993/09/27  17:13:20  yuan
  100.  * LibReadFile, lib_init, and lib_close functions added.
  101.  * Documented in library.h.  
  102.  * 
  103.  * Revision 1.8  1993/09/21  17:22:26  yuan
  104.  * *** empty log message ***
  105.  * 
  106.  * Revision 1.7  1993/09/21  17:16:37  yuan
  107.  * cleaning up
  108.  * 
  109.  * Revision 1.6  1993/09/21  17:06:14  yuan
  110.  * broken and then unbroken version.
  111.  * need to restart the cflib_init stuff from scratch.
  112.  * 
  113.  * Revision 1.5  1993/09/14  13:14:23  yuan
  114.  * additional change which was made in 1.4:
  115.  * If lzw_compress returns a size overflow (*size = -1) then it
  116.  * means that the compression ratio is negative, thus we will
  117.  * store the file rather than compress it.
  118.  * 
  119.  * Revision 1.4  1993/09/14  13:06:41  yuan
  120.  * Major changes made.
  121.  * 1) cfread and cfwrite have been changed into lzw_expand and lzw_compress.
  122.  *     these functions now manipulate buffers rather than files.
  123.  * 2) cfread, cfwrite, cfr_test, and cfw_test have been added.
  124.  *     cfread takes a file and returns a buffer.
  125.  *     cfwrite takes a buffer and writes to a file.
  126.  *     cfr_test and cfw_test are test programs for the previous two
  127.  *     programs and read and write files.
  128.  * 3) extract now returns a buffer rather than passing a buffer as a
  129.  *     parameter.
  130.  * 4) switches are allowed anywhere on the command line now.
  131.  * 5) -a switch added in order to add files to a library.
  132.  * 6) Help message lists available options.
  133.  * 7) Date & Time added to library file headers.
  134.  * 
  135.  * Revision 1.3  1993/09/09  17:42:21  yuan
  136.  * parsarg running off of library
  137.  * parsarg passes full path, so filename is extracted from path
  138.  *   for library.
  139.  * checks to make sure library is not added to itself.
  140.  * checks to make sure '-l' is not called in the middle of a build.
  141.  * 
  142.  * Revision 1.2  1993/09/09  12:38:48  yuan
  143.  * WriteFile and AppendFile fixed.
  144.  * 
  145.  * Revision 1.1  1993/09/08  16:14:46  yuan
  146.  * Initial revision
  147.  * 
  148.  *
  149.  */
  150.  
  151. #pragma off (unreferenced)
  152. static char rcsid[] = "$Id: library.c 1.30 1994/03/23 13:55:30 matt Exp $";
  153. #pragma on (unreferenced)
  154.  
  155. #include <time.h>
  156. #include <stdio.h>
  157. #include <stdlib.h>
  158. #include <string.h>
  159. #include <ctype.h>
  160. #include <stdarg.h>
  161. #include <conio.h>
  162. #include <dos.h>
  163. #include <fcntl.h>
  164. #include <io.h>
  165. #include <sys\types.h>
  166. #include <sys\stat.h>
  167. #include <errno.h>
  168. #include <string.h>
  169.  
  170. #include "library.h"
  171. #include "mem.h"
  172. #include "error.h"
  173.  
  174. int lib_flag;           // library flag
  175. int l_flag;             // listing flag
  176. int b_flag;             // building flag;
  177. int c_flag;             // compression flag
  178. FILE *InputLibFile;     // file to read from
  179. FILE *OutputLibFile;    // file to write to
  180. char *lib_name;         // name of the library
  181. int file_count;         // number of files processed
  182. int headers;            // number of header spaces allocated
  183. char *FileList[MAX_FILES]; // Contains the list of files being processed
  184. file_header Header;     // Holds header info of file being processed
  185.  
  186. file_header *LibHeaderList;
  187. FILE *InputLibInitFile; // file to read from
  188. short init_numfiles;    // number of files in the library
  189.  
  190. int ReadFileBufRaw( char *filename, ubyte *buf, int bufsize )
  191. {
  192.     int length;
  193.     int handle;
  194.  
  195.     handle = open( filename, O_RDONLY | O_BINARY );
  196.     if (handle == -1 ) 
  197.         Error("File %s, %s ",filename,strerror(errno)); 
  198.  
  199.     if (length = read( handle, buf, bufsize ) != bufsize )    
  200.         {
  201.         close( handle );
  202.       Error("File %s, %s ",filename,strerror(errno)); 
  203.         }
  204.     close( handle );
  205.  
  206.     return length;
  207. }
  208.  
  209.  
  210. ubyte *ReadFileRaw( char *filename, int *length )
  211. {
  212.     void *FileData;
  213.     int handle;
  214.  
  215.     handle = open( filename, O_RDONLY | O_BINARY );
  216.     if (handle == -1 )
  217.         return NULL;
  218.         // Error("File %s, %s ",filename,strerror(errno)); 
  219.  
  220.     *length = filelength( handle );
  221.  
  222.  //   MALLOC( FileData, ubyte, *length );//Compile hack again -KRB
  223.     FileData = (ubyte *)malloc(*length*sizeof(ubyte));
  224.  
  225.     if (FileData == NULL )  {
  226.         close( handle );
  227.         Error("File %s, cannot malloc memory",filename);
  228.    }
  229.  
  230.     if (read( handle, FileData, *length ) != *length )    {
  231.         free( FileData );
  232.         close( handle );
  233.       Error("File %s, %s ",filename,strerror(errno)); 
  234.     }
  235.     close( handle );
  236.  
  237.     return FileData;
  238.  
  239. }
  240.  
  241. int AppendFile( char *filename, void *data, int length )
  242. {
  243.     int handle;
  244.  
  245.     handle = open( filename, O_WRONLY | O_CREAT | O_APPEND | O_BINARY , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP );
  246.     if (handle == -1 ) {
  247. //        return ERROR_OPENING_FILE;
  248.         Error("File %s, %s ",filename,strerror(errno)); 
  249.     }
  250.     if (write( handle, data, length )!=length)  {
  251.         close( handle );
  252. //        return ERROR_WRITING_FILE;
  253.         Error("File %s, %s ",filename,strerror(errno)); 
  254.     }
  255.  
  256.     close( handle );
  257.     return 0;
  258. }
  259.  
  260. int WriteFile( char *filename, void *data, int length )
  261. {
  262.     int handle;
  263.  
  264.     handle = open( filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP );
  265.     if (handle == -1 ) {
  266. //        return ERROR_OPENING_FILE;
  267.         Error("File %s, %s ",filename,strerror(errno)); 
  268.     }
  269.     if (write( handle, data, length )!=length)  {
  270.         close( handle );
  271. //        return ERROR_WRITING_FILE;
  272.         Error("File %s, %s ",filename,strerror(errno)); 
  273.     }
  274.  
  275.     close( handle );
  276.     return 0;
  277. }
  278.  
  279.  
  280. int cfwritefile( char *filename, ubyte *buffer, int length ) {
  281.     FILE *output;
  282.     ubyte *compressed;
  283.     int size;
  284.  
  285.     output = fopen( filename, "wb");
  286.  
  287.     putc( 'C', output );
  288.     putc( 'F', output );
  289.     fwrite( &length, sizeof(length), 1, output);
  290.  
  291.     compressed = lzw_compress( buffer, NULL, length, &size);
  292.  
  293.     if (size < 0) {
  294.         printf("    WARNING! : Compressed size larger than original\n");
  295.         printf("                Not storing.\n");
  296.     }
  297.     else {
  298.         fwrite( compressed, sizeof(ubyte), size, output);
  299.         fclose( output );
  300.         free( compressed );
  301.         return LF_LZW;
  302.     }
  303.     return 0;
  304. }
  305.  
  306.  
  307. ubyte *cfreadfile( char *filename, int *size ) {
  308.     FILE *input;
  309.     ubyte *tempbuf;
  310.     ubyte *buf;
  311.     char header[3];
  312.     int length, i;
  313.  
  314.     input = fopen( filename, "rb" );
  315.  
  316.     for (i=0;i<3;i++) header[i]=0;
  317.     for (i=0;i<2;i++)
  318.          header[i] = (char) getc( input );
  319.  
  320.     if (strcmp( header, "CF" )) {
  321.         return NULL;
  322.     }
  323.  
  324.     fread( size, sizeof(int), 1, input);
  325.  
  326.     length = file_size( filename ) - 6;
  327.     //MALLOC( tempbuf, ubyte, length );//Compile hack again -KRB
  328.     tempbuf=(ubyte *)malloc(length*sizeof(ubyte));
  329.     fread( tempbuf, sizeof(ubyte), length, input );
  330.  
  331.     buf = lzw_expand( tempbuf, NULL, *size );
  332.  
  333.     return buf;
  334.  
  335. }
  336.  
  337.  
  338. ubyte *extract( char *library, char *filename ) {
  339.     int i;
  340.     ubyte *buf_ptr;
  341.     ubyte *buf;
  342.     ubyte *tempbuf;
  343.     char header_buf[5];
  344.     short numfiles;
  345.  
  346.     strupr( filename );
  347.     InputLibFile = fopen( library, "rb" );
  348.  
  349.     for (i=0;i<5;i++) header_buf[i]=0;
  350.     for (i=0;i<4;i++)
  351.          header_buf[i] = (char) getc( InputLibFile );
  352.  
  353.     if (strcmp(header_buf, "PSLB")) {
  354.         fclose( InputLibFile );
  355.         return NULL;
  356.     }
  357.     else {
  358.         //numfiles = (short) getc( InputLibFile );
  359.           fread( &numfiles, sizeof(short), 1, InputLibFile );
  360.         for (i=0; i<numfiles; i++) {
  361.            read_data( InputLibFile, &Header );
  362.  
  363.            if (!strcmp(Header.name, filename)) {
  364.                 fseek( InputLibFile, Header.offset, SEEK_SET );
  365.                 //MALLOC(buf, ubyte, Header.original_size);//Compile hack again -KRB
  366.                 buf=(ubyte *)malloc(Header.original_size*sizeof(ubyte));
  367.                 buf_ptr = buf;
  368.  
  369.                 if ( Header.compression == 0 ) {
  370.                     fread( buf, sizeof(ubyte), Header.original_size, InputLibFile );
  371.                 }
  372.  
  373.                     else if ( Header.compression == LF_LZW ) {
  374.                         //MALLOC(tempbuf, ubyte, Header.length);//Compile hack again -KRB
  375.                         tempbuf=(ubyte*)malloc(Header.length*sizeof(ubyte));
  376.                         fread( tempbuf, sizeof(ubyte), Header.length, InputLibFile );
  377.                         lzw_expand( tempbuf, buf, Header.original_size );
  378.                     }
  379.  
  380.                 break;
  381.             }
  382.          }
  383.          if ( i >= numfiles ) return NULL;
  384.  
  385.          fclose( InputLibFile );
  386.          return buf_ptr;
  387.     }
  388. }
  389.  
  390. int read_data( FILE *fp, struct file_header *p )
  391.     {
  392.         return( fread( p, sizeof(*p), 1, fp ) );
  393.     }
  394.  
  395.  
  396. int file_size( char *name ) {
  397.     long eof_ftell;
  398.     FILE *file;
  399.  
  400.     file = fopen( name, "r" );
  401.     if ( file == NULL )
  402.         return( 0L );
  403.     fseek( file, 0L, SEEK_END );
  404.     eof_ftell = ftell( file );
  405.     fclose( file );
  406.     return( eof_ftell );
  407. }
  408.  
  409.  
  410. int ReadFileBuf( char *filename, ubyte *buf, int bufsize ) {
  411.     int i;
  412.     int length;
  413.     ubyte *tempbuf;
  414.  
  415.     strupr( filename );
  416.  
  417.     length = -1;
  418.  
  419.     if (CheckFile( filename )==1)  
  420.          return ReadFileBufRaw( filename, buf, bufsize );
  421.  
  422.     if (lib_flag == 1)
  423.         for ( i=0; i < init_numfiles; i++ ) {
  424.            if (!strcmp(LibHeaderList[i].name, filename)) {
  425.                 fseek( InputLibInitFile, LibHeaderList[i].offset, SEEK_SET );
  426.                 length = LibHeaderList[i].original_size;
  427.     
  428.                 if ( length == bufsize )
  429.                 if ( LibHeaderList[i].compression == 0 ) {
  430.                     //printf("Reading buf size = %d\n", LibHeaderList[i].original_size);
  431.                     fread( buf, sizeof(ubyte), LibHeaderList[i].original_size, InputLibInitFile );
  432.                 }
  433.                     else if ( LibHeaderList[i].compression == LF_LZW ) {
  434.                         //MALLOC(tempbuf, ubyte, LibHeaderList[i].length);//Compile hack again -KRB
  435.                         tempbuf=(ubyte *)malloc( LibHeaderList[i].length*sizeof(ubyte));
  436.                         fread( tempbuf, sizeof(ubyte), LibHeaderList[i].length, InputLibInitFile );
  437.                         lzw_expand( tempbuf, buf, LibHeaderList[i].original_size );
  438.                     }
  439.     
  440.                 break;
  441.             }
  442.          }
  443.         // else 
  444.       //  return ReadFileBufRaw( filename, buf, bufsize );
  445.  
  446.      if ( i >= init_numfiles ) 
  447.             return ReadFileBufRaw( filename, buf, bufsize );
  448.     
  449.     return length;  //buf_ptr;
  450. }
  451.  
  452.  
  453. ubyte *ReadFile( char *filename, int *length ) {
  454.     int i;
  455.     ubyte *buf_ptr;
  456.     ubyte *buf;
  457.     ubyte *tempbuf;
  458.  
  459.     strupr( filename );
  460.  
  461.     *length = -1;
  462.  
  463.      if (CheckFile( filename )==1)
  464.         return ReadFileRaw( filename, length );
  465.  
  466.     if (lib_flag == 1)
  467.         for ( i=0; i < init_numfiles; i++ ) {
  468.            if (!strcmp(LibHeaderList[i].name, filename)) {
  469.                 fseek( InputLibInitFile, LibHeaderList[i].offset, SEEK_SET );
  470.                 //MALLOC(buf, ubyte, LibHeaderList[i].original_size);//Compile hack again -KRB
  471.                 buf=(ubyte *)malloc(LibHeaderList[i].original_size*sizeof(ubyte));
  472.                 buf_ptr = buf;
  473.                 *length = LibHeaderList[i].original_size;
  474.     
  475.                 if ( LibHeaderList[i].compression == 0 ) {
  476.                     //printf("Reading buf size = %d\n", LibHeaderList[i].original_size);
  477.                     fread( buf, sizeof(ubyte), LibHeaderList[i].original_size, InputLibInitFile );
  478.                 }
  479.     
  480.                     else if ( LibHeaderList[i].compression == LF_LZW ) {
  481.                         //MALLOC(tempbuf, ubyte, LibHeaderList[i].length);//Compile hack again -KRB
  482.                         tempbuf=(ubyte *)malloc(LibHeaderList[i].length*sizeof(ubyte));
  483.                         fread( tempbuf, sizeof(ubyte), LibHeaderList[i].length, InputLibInitFile );
  484.                         lzw_expand( tempbuf, buf, LibHeaderList[i].original_size );
  485.                     }
  486.     
  487.                 break;
  488.             }
  489.          } 
  490.             //else
  491.                 //return ReadFileRaw( filename, length );
  492.  
  493.      if ( i >= init_numfiles )
  494.             return ReadFileRaw( filename, length );
  495.  
  496.      return buf_ptr;
  497. }
  498.  
  499.  
  500. //returns error codes listed in cflib.h
  501. int lib_init( char *init_lib_name ) {
  502.  
  503.     char header_buf[5];
  504.     int i;
  505.     short temp;
  506.  
  507.     InputLibInitFile = fopen( init_lib_name, "rb" );
  508.  
  509.      if (! InputLibInitFile) return LI_NO_FILE;
  510.  
  511.     for (i=0;i<5;i++) header_buf[i]=0;
  512.     for (i=0;i<4;i++)
  513.          header_buf[i] = (char) getc( InputLibInitFile );
  514.  
  515.     if (strcmp(header_buf, "PSLB")) {
  516.         fclose( InputLibInitFile );
  517.         return LI_NOT_PSLIB;
  518.     }
  519.  
  520.     //init_numfiles = (short) getc( InputLibInitFile );
  521.      fread( &temp, sizeof(short), 1, InputLibInitFile );
  522.     init_numfiles = temp;
  523.  
  524.    // MALLOC ( LibHeaderList, file_header, init_numfiles );//Compile hack again -KRB
  525.       LibHeaderList=(file_header *)malloc(init_numfiles*sizeof(file_header));
  526.      if (! LibHeaderList) {
  527.         fclose(InputLibInitFile);
  528.        return LI_NO_MEM;
  529.      }
  530.  
  531.     fread( LibHeaderList, sizeof( *LibHeaderList ), init_numfiles, InputLibInitFile );
  532.     atexit(lib_close);
  533.  
  534.     lib_flag = 1;                    //everything is ok, so mark as open
  535.     return LI_NO_ERROR;
  536. }
  537.  
  538. void lib_close() {
  539.  
  540.     fclose( InputLibInitFile );
  541.      free (LibHeaderList);
  542.      lib_flag = 0;
  543.  
  544. }
  545.  
  546. void init_library( char *filename, int numfiles ) {
  547.  
  548.     lib_header Lib_Header;
  549.     int i;
  550.     ubyte nul;
  551.     short temp;
  552.     
  553.     OutputLibFile = fopen( filename, "wb");
  554.     strcpy( Lib_Header.id, "PSLB" );
  555.     Lib_Header.nfiles = numfiles;
  556.  
  557.     for ( i=0; i<4 ; i++ ) putc( Lib_Header.id[i], OutputLibFile );
  558.      temp = Lib_Header.nfiles;
  559.     //putc( Lib_Header.nfiles, OutputLibFile );
  560.         temp = Lib_Header.nfiles;
  561.      fwrite( &temp, sizeof(short), 1, OutputLibFile );
  562.  
  563.     nul = 0;
  564.     for ( i=0; i<numfiles; i++ ) fwrite( &nul, sizeof(nul), 32, OutputLibFile );
  565.  
  566.     fclose( OutputLibFile );
  567.  
  568. }
  569.  
  570. void write_file_header( char *filename, file_header Header ) {
  571.  
  572.     OutputLibFile = fopen( filename, "rb+" );
  573.  
  574.     fseek( OutputLibFile, 4+sizeof(short)+32*(file_count-1), SEEK_SET );
  575.     fwrite( &Header, sizeof(file_header), 1, OutputLibFile );
  576.     fclose( OutputLibFile );
  577. }
  578.  
  579.  
  580.  
  581. int CheckFile( char *filename ) {
  582.    int i;
  583.    int handle;
  584.  
  585.    strupr( filename );
  586.  
  587.     handle = open( filename, O_RDONLY | O_BINARY );
  588.     if (handle != -1)
  589.         {
  590.         close( handle );
  591.         return 1;
  592.         }
  593.  
  594.     close(handle);
  595.     
  596.    if (lib_flag == 1)
  597.         for ( i=0; i < init_numfiles; i++ ) 
  598.             if (!strcmp(LibHeaderList[i].name, filename))
  599.                 return 2;
  600.         
  601.     return 0;
  602.     
  603. }
  604.  
  605. FILE * LibraryGetFileInfo( char *filename, int * others_use, int * lib_offset, int * file_size, int * org_size, int * compressed, char * buffer ) {
  606.     int i;
  607.     FILE * lib_file;
  608.     char signature[3];
  609.  
  610.     strupr( filename );
  611.  
  612.     lib_file = fopen( filename, "rb" );
  613.     if (lib_file)    {
  614.         if (buffer)
  615.             setvbuf( lib_file, buffer, _IOFBF, 4096*2 );
  616.         *file_size = filelength( fileno( lib_file ));
  617.         fread( signature, 2, sizeof(char), lib_file );
  618.         signature[2] = '\0';
  619.         if (!strcmp( signature, "CF" ))    {
  620.             fread( org_size, 1, sizeof(int), lib_file );
  621.             *lib_offset = 6L;        // Offset is CF+Length into file
  622.             *compressed = 1;
  623.         } else {
  624.             *org_size = *file_size;
  625.             *lib_offset = 0;
  626.             fseek( lib_file, 0L, SEEK_SET );
  627.             *compressed = 0;
  628.         }
  629.         *others_use = 0;
  630.         return lib_file;
  631.     }
  632.  
  633.     if (lib_flag == 1)    
  634.         for ( i=0; i < init_numfiles; i++ ) {
  635.            if (!strcmp(LibHeaderList[i].name, filename)) {
  636.                     lib_file = InputLibInitFile;
  637.                     *lib_offset = LibHeaderList[i].offset;
  638.                     *org_size = LibHeaderList[i].original_size;
  639.                     *file_size = LibHeaderList[i].length;
  640.                     *compressed = (LibHeaderList[i].compression == LF_LZW );
  641.                     *others_use = 1;
  642.                     return lib_file;
  643.             }
  644.          }
  645.  
  646.     lib_file = NULL;
  647.     *others_use = 0;
  648.     *lib_offset = 0;
  649.     *org_size = 0;
  650.     *file_size = 0;
  651.     *compressed=0;
  652.     return lib_file;
  653.  
  654. }
  655.  
  656.