#ifndef _COMP_H_ #define _COMP_H_ #ifndef COMP_ENCODE #define COMP_ENCODE 1 /* 1 if you need encoding, 0 otherwise */ #endif #ifndef COMP_DECODE #define COMP_DECODE 1 /* 1 if you need decoding, 0 otherwise */ #endif /* ---------------------------- Error codes --------------------------- */ /* ----------- */ #define COMP_ERR_NONE 0 /* everything is OK */ #define COMP_ERR_OPEN 1 /* cannot open input file */ #define COMP_ERR_READ 2 /* input file read error */ #define COMP_ERR_CREATE 3 /* cannot create output file */ #define COMP_ERR_WRITE 4 /* output file write error */ #define COMP_ERR_NOMEM 5 /* no enough memory */ #define COMP_ERR_BROKEN 6 /* damaged compressed data */ #define COMP_ERR_PARAM 7 /* incorrect function parameter */ #define COMP_ERR_LOCKED 8 /* this block (or file -- when attempting */ /* to close a file) is used by another */ /* thread or process; request cannot be */ /* performed until previous operation is */ /* complete */ #define COMP_ERR_INTERNAL 9 /* everything else is internal error */ /* hopefully it should never happen */ /* Almost all functions listed further return one as its result on of */ /* codes given above: if no error occured then COMP_ERR_NONE (i.e. 0) */ /* is returned, otherwise functions return error code plus number of */ /* line in "comp.c" where the error was detected multiplied by 256; */ /* line number may be used for exact specification of a place where */ /* error was detected thus making debugging slightly simpler. */ /* */ /* Thus, "(code & 0xff)" gives proper error code, and "(code >> 8)" */ /* gives number of line where the error was raised. */ /* ------------------------- Data structures -------------------------- */ /* --------------- */ typedef struct { const int dummy; } *COMP_FILE; /* Pointer to compressed data file (anonymous data type) */ typedef struct COMP_BLOCK_T { const unsigned char *const ptr; /* pointer to the first decoded byte */ const int decoded; /* number of bytes decoded so far */ const int total; /* total number of bytes in block */ const int number; /* number of this block */ const COMP_FILE file; /* pointer to the file it belongs */ } *COMP_BLOCK; /* Pointer to compressed data block */ typedef struct { int dummy; } *COMP_STAT; /* Pointer to some statistical information about original data */ /* ----------------------- Function prototypes ------------------------ */ /* ------------------- */ #if COMP_ENCODE int comp_max_block (void); /* RETURNS: max size of block */ int comp_analyze_file (COMP_STAT * ret_stat, char *name, int block_size); /* DESCRIPTION: analyzes data file and evaluates some statistical */ /* information used by "comp_encode_file ()" function later on. */ /* */ /* */ /* PLEASE NOTICE that if you are about to compress several files with */ /* similar statistics (i.e. generated by stationary ergodic source) you */ /* may use the same parameters to compress all the files; it may save */ /* you a lot of time because such an analysys may take as much time as */ /* proper compression. */ /* */ /* RETURNS: error code */ /* */ /* "name" -- file name to analyze */ /* "block_size" -- size of block (will be rounded down to largest power */ /* of two not exceeding "block_size"; if "block_size" */ /* exceeds "comp_max_block ()" it will be rounded down */ /* "stat" -- piece of memory to write some information and magics */ int comp_encode_file (char *orig, char *comp, int block_size, COMP_STAT stat); /* DESCRIPTION: encodes "orig" file into "comp" splitting it into */ /* blocks of "block_size" bytes compressed independently using */ /* statistical information in "info" previousely gathered by */ /* "comp_analyze_file ()". */ /* */ /* RETURNS: error code */ /* */ /* "orig" -- original data file name */ /* "comp" -- name of file to write compressed data */ /* "block_size" -- size of block (will be rounded down to largest */ /* power of two not exceeding "block_size"; if */ /* "block_size" exceeds "comp_max_block ()" it will be */ /* rounded down */ /* "stat" -- statistics gathered by "comp_analyze_file" */ #endif /* COMP_ENCODE */ #if COMP_DECODE int comp_open_file (COMP_FILE * ret_file, char *name, int check_crc); /* DESCRIPTION: open compressed file, read its header, ensure it is */ /* valid, build internal data structures required by decoder and save a */ /* pointer to such structure into location referenced by "ret_info". */ /* */ /* PLEASE NOTICE that this function opens and preserves a pointer to */ /* "FILE *" stream which will be later used to read blocks from */ /* compressed file. Thus you should use "comp_close_file ()" function */ /* close the "FILE *" stream and release memory occupied by internal */ /* data structures. */ /* */ /* RETURNS: error code */ /* */ /* "ret_file" -- address of "void *" pointer which will be set to 0 */ /* if anything goes wrong, and will point to some */ /* internal data structure on success */ /* "name" -- name of file with compressed data */ /* "check_crc" -- if non-zero then CRC32 of each compressed block will */ /* be evaluated and compared with correct value when */ /* loading block (see "comp_read_block ()" function */ /* later on) */ char *comp_file_name (COMP_FILE file); /* RETURNS: a pointer to the string containg name of file which is */ /* duplicated by "comp_open_file ()" function. */ /* */ /* "file" -- pointer initialized by "comp_open_file ()" */ int comp_log_block_size (COMP_FILE file); /* DESCRIPTION: return log base 2 of a block size. It is up to user to */ /* provide decoder with 2 (two) pieces of memory for each block to */ /* decode each of "(1 << comp_log_block_size ()) + 32" bytes to store */ /* original and compressed data (when block is entirely decoded the */ /* memory for compressed data is not needed for decoder anymore so you */ /* may reuse it the way you like. */ /* */ /* RETURNS: log base 2 of block size on success (if "info" was */ /* correctly initialized by "comp_open_file ()", -1 otherwise */ /* */ /* "file" -- pointer initialized by "comp_open_file ()" */ int comp_tell_blocks (COMP_FILE file); /* DESCRIPTION: return the number of blocks in data stream. */ /* */ /* RETURNS: number of blocks [of "(1 << comp_log_block_size ())" bytes */ /* each probably except for the last one] if "info" is correctly set up */ /* by "comp_open_file ()", or "(-1)" otherwise. */ /* */ /* "file" -- pointer initialized by "comp_open_file ()" */ int comp_alloc_block (COMP_BLOCK * ret_block, COMP_FILE file); /* DESCRIPTION: allocates a block for decoding of data stored in */ /* "file" and registers new block which uses "file". */ /* */ /* PLEASE NOTICE that "COMP_BLOCK" is much larger structure than shown */ /* above therefore it should be released via "comp_free_block ()" call. */ /* */ /* RETURNS: error code */ /* */ /* "ret_block" -- address of variable of "COMP_BLOCK" type where */ /* pointer to allocated block will be written on */ /* success, or NULL assigned on failure */ /* "file" -- pointer initialized by "comp_open_file ()" */ int comp_read_block (COMP_BLOCK block, int number); /* DESCRIPTION: read compressed block of data number "number" into */ /* "block" and compare compressed data check sum with the value stored */ /* in compressed file header (which was loaded by "comp_open_file ()"). */ /* */ /* PLEASE NOTICE that check sum is evaluated and compared if and only */ /* if "comp_open_file ()" was called with non-zero value of parameter */ /* "check_crc". */ /* */ /* RETURNS: error code */ /* */ /* "block" -- pointer initialized by "comp_open_file ()" */ int comp_decode_block (COMP_BLOCK block, int bytes); /* DESCRIPTION: ensure that at least "bytes" bytes of data in "block" */ /* is decoded and decode more if necessary. */ /* */ /* PLEASE NOTICE that decoder is incremental: decoding is stopped as */ /* soon as "bytes" bytes or bit more are decoded. If later more you */ /* need more bytes from the block you should call "comp_decode_block */ /* ()" one again with larger value of "bytes" preferably using the same */ /* "block" pointer so that first bytes decoded earlier will not be */ /* decoded again. */ /* */ /* RETURNS: error code */ /* */ /* "block" -- pointer initialized by "comp_open_file ()" */ int comp_check_crc (COMP_BLOCK block); /* DESCRIPTION: decode entire contents of block, evaluate control check */ /* sum of decoded block contents and compare with preserved value */ /* stored in compressed file header which is loaded by "comp_open_file */ /* ()" function. */ /* */ /* PLEASE NOTICE that decoding is performed, check sum is evaluated and */ /* compared if and only if "comp_open_file ()" was called with non-zero */ /* value of parameter "check_crc". */ /* */ /* RETURNS: error code */ /* */ /* "block" -- pointer initialized by "comp_open_file ()" */ int comp_free_block (COMP_BLOCK block); /* DESCRIPTION: release memory allocated by "block" and unregister it */ /* from compressed file it belongs. */ /* */ /* PLEASE NOTICE that all blocks be released befor closing the file. */ /* */ /* RETURNS: error code */ /* */ /* "block" -- pointer initialized by "comp_open_file ()" */ int comp_close_file (COMP_FILE file); /* DESCRIPTION: close "FILE *" data stream and release all the memory */ /* allocated by "comp_open_file ()" function. */ /* */ /* PLEASE NOTICE that file cannot be closed until all blocks connected */ /* with it by "comp_alloc_block ()" are released by "comp_free_block */ /* ()". */ /* */ /* RETURNS: error code */ /* */ /* "file" -- pointer to internal data structure returned by */ /* "comp_open_file ()" function */ #endif /* COMP_DECODE */ #endif /* _COMP_H_ */