00001 #ifndef UTIL_COMPRESS__LZO__HPP 00002 #define UTIL_COMPRESS__LZO__HPP 00003 00004 /* $Id: lzo.hpp 145414 2008-11-12 16:10:03Z ivanov $ 00005 * =========================================================================== 00006 * 00007 * PUBLIC DOMAIN NOTICE 00008 * National Center for Biotechnology Information 00009 * 00010 * This software/database is a "United States Government Work" under the 00011 * terms of the United States Copyright Act. It was written as part of 00012 * the author's official duties as a United States Government employee and 00013 * thus cannot be copyrighted. This software/database is freely available 00014 * to the public for use. The National Library of Medicine and the U.S. 00015 * Government have not placed any restriction on its use or reproduction. 00016 * 00017 * Although all reasonable efforts have been taken to ensure the accuracy 00018 * and reliability of the software and data, the NLM and the U.S. 00019 * Government do not and cannot warrant the performance or results that 00020 * may be obtained by using this software or data. The NLM and the U.S. 00021 * Government disclaim all warranties, express or implied, including 00022 * warranties of performance, merchantability or fitness for any particular 00023 * purpose. 00024 * 00025 * Please cite the author in any work or product based on this material. 00026 * 00027 * =========================================================================== 00028 * 00029 * Author: Vladimir Ivanov 00030 * 00031 */ 00032 00033 /// @file lzo.hpp 00034 /// LZO Compression API. 00035 /// 00036 /// LZO is a data compression library which is suitable for data 00037 /// (de)compression in real-time. This means it favours speed 00038 /// over compression ratio. 00039 /// 00040 /// We don't support all possible algorithms, implemented in LZO. 00041 /// Only LZO1X is used in this API. Author of LZO says that it is 00042 /// often the best choice of all. 00043 /// 00044 /// CLZOCompression - base methods for compression/decompression 00045 /// memory buffers and files. 00046 /// CLZOCompressionFile - allow read/write operations on files. 00047 /// LZO doesn't support files, so we use here 00048 /// our own file format (very simple). 00049 /// CLZOCompressor - LZO based compressor 00050 /// (used in CLZOStreamCompressor). 00051 /// CLZODecompressor - LZO based decompressor 00052 /// (used in CLZOStreamDecompressor). 00053 /// CLZOStreamCompressor - LZO based compression stream processor 00054 /// (see util/compress/stream.hpp for details). 00055 /// CLZOStreamDecompressor - LZO based decompression stream processor 00056 /// (see util/compress/stream.hpp for details). 00057 /// 00058 /// For more details see LZO documentation: 00059 /// http://www.oberhumer.com/opensource/lzo/ 00060 00061 00062 #include <util/compress/stream.hpp> 00063 00064 #if defined(HAVE_LIBLZO) 00065 00066 #include <stdio.h> 00067 #ifdef HAVE_LIBLZO2 // rigged to imply HAVE_LIBLZO. 00068 # include <lzo/lzo1x.h> 00069 #else 00070 # include <lzo1x.h> 00071 #endif 00072 00073 /** @addtogroup Compression 00074 * 00075 * @{ 00076 */ 00077 00078 BEGIN_NCBI_SCOPE 00079 00080 00081 ////////////////////////////////////////////////////////////////////////////// 00082 // 00083 // Special compression parameters (description partialy copied from LZO docs): 00084 // 00085 // <blocksize> 00086 // LZO is a block compression algorithm - it compresses and decompresses 00087 // a block of data. Block size must be the same for compression 00088 // and decompression. Default value is 256K (262144 bytes). 00089 // This parameter define a block size used only for file/stream based 00090 // compression/decompression. The methods operated with all data located 00091 // in memory (like CompressBuffer/DecompressBuffer) works by default with 00092 // one big block - the whole data buffer. 00093 // 00094 00095 /// Default LZO block size. 00096 /// 00097 /// We use such block size to reduce overhead with a stream processor's 00098 /// methods calls, because compression/decompression output streams use 00099 /// by default 16Kb - 1 as output buffer size. 00100 /// @sa CCompressionStreambuf::CCompressionStreambuf 00101 const size_t kLZODefaultBlockSize = 24*1024; 00102 00103 00104 ///////////////////////////////////////////////////////////////////////////// 00105 /// 00106 /// CLZOCompression -- 00107 /// 00108 /// Define a base methods for compression/decompression memory buffers 00109 /// and files. 00110 00111 class CLZOCompression : public CCompression 00112 { 00113 public: 00114 /// Compression/decompression flags. 00115 enum EFlags { 00116 ///< Allow transparent reading data from buffer/file/stream 00117 ///< regardless is it compressed or not. But be aware, 00118 ///< if data source contains broken data and API cannot detect that 00119 ///< it is compressed data, that you can get binary instead of 00120 ///< decompressed data. By default this flag is OFF. 00121 fAllowTransparentRead = (1<<0), 00122 ///< Add/check (accordingly to compression or decompression) 00123 ///< the compressed data checksum. A checksum is a form of 00124 ///< redundancy check. We use the safe decompressor, but this can be 00125 ///< not enough, because many data errors will not result in 00126 ///< a compressed data violation. 00127 fChecksum = (1<<1), 00128 ///< Use stream compatible format for data compression. 00129 ///< This flag have an effect only for CompressBuffer/DecompressBuffer. 00130 ///< File and stream based compressors always use it by default. 00131 ///< Use this flag with DecompressBuffer() to decompress data, 00132 ///< compressed using streams, or compress data with CompressBuffer(), 00133 ///< that can be decompressed using decompression stream. 00134 fStreamFormat = (1<<2), 00135 ///< Store file information like file name and file modification date 00136 ///< of the compressed file into the file/stream. 00137 ///< Works only with fStreamFormat flag. 00138 fStoreFileInfo = (1<<3) | fStreamFormat 00139 }; 00140 /// Define a pointer to LZO1X compression function. 00141 typedef int(*TLZOCompressionFunc) 00142 ( const lzo_bytep src, lzo_uint src_len, 00143 lzo_bytep dst, lzo_uintp dst_len, 00144 lzo_voidp wrkmem ); 00145 00146 /// Structure to define parameters for some level of compression. 00147 struct SCompressionParam { 00148 TLZOCompressionFunc compress; ///< Pointer to compression function. 00149 lzo_uint workmem; ///< Size of working memory for compressor. 00150 }; 00151 00152 /// Constructor. 00153 CLZOCompression( 00154 ELevel level = eLevel_Default, 00155 size_t blocksize = kLZODefaultBlockSize 00156 ); 00157 00158 /// Destructor. 00159 virtual ~CLZOCompression(void); 00160 00161 /// Return name and version of the compression library. 00162 virtual CVersionInfo GetVersion(void) const; 00163 00164 /// Initialize LZO library. 00165 /// 00166 /// You shoud call this method only once, before any real 00167 /// compression/decompression operations. 00168 /// @li <b>Multi-Thread safety:</b> 00169 /// If you are using this API in a multi-threaded application, and there 00170 /// is more than one thread using this API, it is safe to call 00171 /// Initialize() explicitly in the beginning of your main thread, 00172 /// before you run any other threads. 00173 static bool Initialize(void); 00174 00175 /// Get compression level. 00176 /// 00177 /// NOTE: LZO library used only 2 compression levels for used in this API 00178 /// LZO1X algorithm. So, all levels will be translated only to 2 real 00179 /// value. We use LZO1X-999 for "eLevel_Best", and LZO1X-1 for 00180 /// all other levels of compression. 00181 virtual ELevel GetLevel(void) const; 00182 00183 /// Returns default compression level for a compression algorithm. 00184 virtual ELevel GetDefaultLevel(void) const 00185 { return eLevel_Lowest; }; 00186 00187 // 00188 // Utility functions 00189 // 00190 00191 /// Compress data in the buffer. 00192 /// 00193 /// Altogether, the total size of the destination buffer must be little 00194 /// more then size of the source buffer. 00195 /// @param src_buf 00196 /// [in] Source buffer. 00197 /// @param src_len 00198 /// [in] Size of data in source buffer. 00199 /// @param dst_buf 00200 /// [in] Destination buffer. 00201 /// @param dst_size 00202 /// [in] Size of destination buffer. 00203 /// @param dst_len 00204 /// [out] Size of compressed data in destination buffer. 00205 /// @return 00206 /// Return TRUE if operation was succesfully or FALSE otherwise. 00207 /// On success, 'dst_buf' contains compressed data of dst_len size. 00208 /// @sa 00209 /// EstimateCompressionBufferSize, DecompressBuffer 00210 virtual bool CompressBuffer( 00211 const void* src_buf, size_t src_len, 00212 void* dst_buf, size_t dst_size, 00213 /* out */ size_t* dst_len 00214 ); 00215 00216 /// Decompress data in the buffer. 00217 /// 00218 /// @param src_buf 00219 /// Source buffer. 00220 /// @param src_len 00221 /// Size of data in source buffer. 00222 /// @param dst_buf 00223 /// Destination buffer. 00224 /// @param dst_len 00225 /// Size of destination buffer. 00226 /// @param dst_len 00227 /// Size of decompressed data in destination buffer. 00228 /// @return 00229 /// Return TRUE if operation was succesfully or FALSE otherwise. 00230 /// On success, 'dst_buf' contains decompressed data of dst_len size. 00231 /// @sa 00232 /// CompressBuffer 00233 virtual bool DecompressBuffer( 00234 const void* src_buf, size_t src_len, 00235 void* dst_buf, size_t dst_size, 00236 /* out */ size_t* dst_len 00237 ); 00238 00239 /// Estimate buffer size for data compression. 00240 /// 00241 /// Simplified method for estimation of the size of buffer required 00242 /// to compress specified number of bytes of data. 00243 /// @sa 00244 /// EstimateCompressionBufferSize, CompressBuffer 00245 size_t EstimateCompressionBufferSize(size_t src_len, 00246 size_t blocksize = 0); 00247 00248 /// Estimate buffer size for data compression. 00249 /// 00250 /// The function shall estimate the size of buffer required to compress 00251 /// specified number of bytes of data. This function return a conservative 00252 /// value that larger than 'src_len'. 00253 /// @param src_len 00254 /// Size of data in source buffer. 00255 /// @blocksize 00256 /// Size of blocks used by compressor to compress source data. 00257 /// Value 0 means that will be used block size specified in constructor. 00258 /// @flags 00259 /// Flags that will be used for compression. 00260 /// @return 00261 /// Estimated buffer size. 00262 /// @sa 00263 /// CompressBuffer 00264 size_t EstimateCompressionBufferSize(size_t src_len, 00265 size_t blocksize, 00266 TFlags flags); 00267 /// Compress file. 00268 /// 00269 /// @param src_file 00270 /// File name of source file. 00271 /// @param dst_file 00272 /// File name of result file. 00273 /// @param buf_size 00274 /// Buffer size used to read/write files. 00275 /// @return 00276 /// Return TRUE on success, FALSE on error. 00277 /// @sa 00278 /// DecompressFile 00279 virtual bool CompressFile( 00280 const string& src_file, 00281 const string& dst_file, 00282 size_t buf_size = kCompressionDefaultBufSize 00283 ); 00284 00285 /// Decompress file. 00286 /// 00287 /// @param src_file 00288 /// File name of source file. 00289 /// @param dst_file 00290 /// File name of result file. 00291 /// @param buf_size 00292 /// Buffer size used to read/write files. 00293 /// @return 00294 /// Return TRUE on success, FALSE on error. 00295 /// @sa 00296 /// CompressFile 00297 virtual bool DecompressFile( 00298 const string& src_file, 00299 const string& dst_file, 00300 size_t buf_size = kCompressionDefaultBufSize 00301 ); 00302 00303 /// Structure to keep compressed file information. 00304 struct SFileInfo { 00305 string name; 00306 string comment; 00307 time_t mtime; 00308 SFileInfo(void) : mtime(0) {}; 00309 }; 00310 00311 protected: 00312 /// Initialize compression parameters. 00313 void InitCompression(ELevel level); 00314 00315 /// Get error description for specified error code. 00316 const char* GetLZOErrorDescription(int errcode); 00317 00318 /// Format string with last error description. 00319 string FormatErrorMessage(string where) const; 00320 00321 /// Compress block of data. 00322 /// 00323 /// @return 00324 /// Return compressor error code. 00325 int CompressBlock(const lzo_bytep src_buf, lzo_uint src_len, 00326 lzo_bytep dst_buf, lzo_uintp dst_len /* out */); 00327 00328 /// Compress block of data for stream format (fStreamFormat flag). 00329 /// 00330 /// @return 00331 /// Return compressor error code. 00332 int CompressBlockStream( 00333 const lzo_bytep src_buf, lzo_uint src_len, 00334 lzo_bytep dst_buf, lzo_uintp dst_len /* out */); 00335 00336 /// Decompress block of data. 00337 /// 00338 /// @return 00339 /// Return decompressor error code. 00340 int DecompressBlock(const lzo_bytep src_buf, lzo_uint src_len, 00341 lzo_bytep dst_buf, lzo_uintp dst_len /* out */, 00342 TFlags flags); 00343 00344 /// Decompress block of data for stream format (fStreamFormat flag). 00345 /// 00346 /// @return 00347 /// Return decompressor error code. 00348 int DecompressBlockStream( 00349 const lzo_bytep src_buf, lzo_uint src_len, 00350 lzo_bytep dst_buf, lzo_uintp dst_len /* out */, 00351 TFlags flags, 00352 lzo_uintp processed /* out */); 00353 00354 protected: 00355 size_t m_BlockSize; ///< Block size for (de)compression. 00356 // Compression parameters 00357 AutoArray<char> m_WorkMem; ///< Working memory for compressor. 00358 SCompressionParam m_Param; ///< Compression parameters. 00359 }; 00360 00361 00362 ////////////////////////////////////////////////////////////////////////////// 00363 /// 00364 /// CLZOCompressionFile class -- 00365 /// 00366 /// Throw exceptions on critical errors. 00367 00368 class CLZOCompressionFile : public CLZOCompression, 00369 public CCompressionFile 00370 { 00371 public: 00372 /// Constructor. 00373 /// For a special parameters description see CLZOCompression. 00374 CLZOCompressionFile( 00375 const string& file_name, 00376 EMode mode, 00377 ELevel level = eLevel_Default, 00378 size_t blocksize = kLZODefaultBlockSize 00379 ); 00380 00381 /// Conventional constructor. 00382 /// For a special parameters description see CLZOCompression. 00383 CLZOCompressionFile( 00384 ELevel level = eLevel_Default, 00385 size_t blocksize = kLZODefaultBlockSize 00386 ); 00387 00388 /// Destructor 00389 ~CLZOCompressionFile(void); 00390 00391 /// Opens a compressed file for reading or writing. 00392 /// 00393 /// @param file_name 00394 /// File name of the file to open. 00395 /// @param mode 00396 /// File open mode. 00397 /// @return 00398 /// TRUE if file was opened succesfully or FALSE otherwise. 00399 /// @sa 00400 /// CLZOCompression, Read, Write, Close 00401 virtual bool Open(const string& file_name, EMode mode); 00402 00403 /// Opens a compressed file for reading or writing. 00404 /// 00405 /// Do the same as standard Open(), but can also get/set file info. 00406 /// @param file_name 00407 /// File name of the file to open. 00408 /// @param mode 00409 /// File open mode. 00410 /// @param info 00411 /// Pointer to file information structure. If it is not NULL, 00412 /// that it will be used to get information about compressed file 00413 /// in the read mode, and set it in the write mode for compressed 00414 /// files. 00415 /// @return 00416 /// TRUE if file was opened succesfully or FALSE otherwise. 00417 /// @sa 00418 /// CLZOCompression, Read, Write, Close 00419 virtual bool Open(const string& file_name, EMode mode, SFileInfo* info); 00420 00421 /// Read data from compressed file. 00422 /// 00423 /// Read up to "len" uncompressed bytes from the compressed file "file" 00424 /// into the buffer "buf". 00425 /// @param buf 00426 /// Buffer for requested data. 00427 /// @param len 00428 /// Number of bytes to read. 00429 /// @return 00430 /// Number of bytes actually read (0 for end of file, -1 for error). 00431 /// The number of really readed bytes can be less than requested. 00432 /// @sa 00433 /// Open, Write, Close 00434 virtual long Read(void* buf, size_t len); 00435 00436 /// Write data to compressed file. 00437 /// 00438 /// Writes the given number of uncompressed bytes from the buffer 00439 /// into the compressed file. 00440 /// @param buf 00441 /// Buffer with written data. 00442 /// @param len 00443 /// Number of bytes to write. 00444 /// @return 00445 /// Number of bytes actually written or -1 for error. 00446 /// @sa 00447 /// Open, Read, Close 00448 virtual long Write(const void* buf, size_t len); 00449 00450 /// Close compressed file. 00451 /// 00452 /// Flushes all pending output if necessary, closes the compressed file. 00453 /// @return 00454 /// TRUE on success, FALSE on error. 00455 /// @sa 00456 /// Open, Read, Write 00457 virtual bool Close(void); 00458 00459 protected: 00460 EMode m_Mode; ///< I/O mode (read/write). 00461 CNcbiFstream* m_File; ///< File stream. 00462 CCompressionIOStream* m_Stream; ///< [De]comression stream. 00463 }; 00464 00465 00466 ///////////////////////////////////////////////////////////////////////////// 00467 /// 00468 /// CLZOBuffer -- 00469 /// 00470 /// Auxiliary base class for stream compressor/decompressor to manage 00471 /// buffering of data for LZO blocking I/O. 00472 /// 00473 /// @sa CLZOCompressor, CLZODecompressor 00474 00475 class CLZOBuffer 00476 { 00477 public: 00478 /// Constructor. 00479 CLZOBuffer(void); 00480 00481 protected: 00482 /// Reset internal state. 00483 void ResetBuffer(size_t in_bufsize, size_t out_bufsize); 00484 00485 private: 00486 size_t m_Size; ///< Size of In/Out buffers. 00487 AutoArray<char> m_Buf; ///< Buffer for caching (size of m_Size*2). 00488 char* m_InBuf; ///< Pointer to input buffer. 00489 size_t m_InSize; ///< Size of the input buffer. 00490 size_t m_InLen; ///< Length of data in the input buffer. 00491 char* m_OutBuf; ///< Pointer to output buffer. 00492 size_t m_OutSize; ///< Size of the output buffer. 00493 char* m_OutBegPtr; ///< Pointer to begin of data in out buffer. 00494 char* m_OutEndPtr; ///< Pointer to end of data in out buffer. 00495 00496 // Friend classes 00497 friend class CLZOCompressor; 00498 friend class CLZODecompressor; 00499 }; 00500 00501 00502 ///////////////////////////////////////////////////////////////////////////// 00503 /// 00504 /// CLZOCompressor -- LZO based compressor 00505 /// 00506 /// Used in CLZOStreamCompressor. 00507 /// @sa CLZOStreamCompressor, CLZOCompression, CCompressionProcessor 00508 00509 class CLZOCompressor : public CLZOCompression, 00510 public CCompressionProcessor, 00511 public CLZOBuffer 00512 { 00513 public: 00514 /// Constructor. 00515 CLZOCompressor( 00516 ELevel level = eLevel_Default, 00517 size_t blocksize = kLZODefaultBlockSize, 00518 CCompression::TFlags flags = 0 00519 ); 00520 /// Destructor. 00521 virtual ~CLZOCompressor(void); 00522 00523 /// Set information about compressed file. 00524 void SetFileInfo(const SFileInfo& info); 00525 00526 protected: 00527 virtual EStatus Init (void); 00528 virtual EStatus Process(const char* in_buf, size_t in_len, 00529 char* out_buf, size_t out_size, 00530 /* out */ size_t* in_avail, 00531 /* out */ size_t* out_avail); 00532 virtual EStatus Flush (char* out_buf, size_t out_size, 00533 /* out */ size_t* out_avail); 00534 virtual EStatus Finish (char* out_buf, size_t out_size, 00535 /* out */ size_t* out_avail); 00536 virtual EStatus End (void); 00537 00538 protected: 00539 /// Compress block of data in the cache buffer. 00540 bool CompressCache(void); 00541 00542 private: 00543 bool m_NeedWriteHeader; ///< TRUE if needed to write a header. 00544 SFileInfo m_FileInfo; ///< Compressed file info. 00545 }; 00546 00547 00548 ///////////////////////////////////////////////////////////////////////////// 00549 /// 00550 /// CLZODecompressor -- LZO based decompressor 00551 /// 00552 /// Used in CLZOStreamCompressor. 00553 /// @sa CLZOStreamCompressor, CLZOCompression, CCompressionProcessor 00554 00555 class CLZODecompressor : public CLZOCompression, 00556 public CCompressionProcessor, 00557 public CLZOBuffer 00558 { 00559 public: 00560 /// Constructor. 00561 CLZODecompressor( 00562 size_t blocksize = kLZODefaultBlockSize, 00563 CCompression::TFlags flags = 0 00564 ); 00565 00566 /// Destructor. 00567 virtual ~CLZODecompressor(void); 00568 00569 protected: 00570 virtual EStatus Init (void); 00571 virtual EStatus Process(const char* in_buf, size_t in_len, 00572 char* out_buf, size_t out_size, 00573 /* out */ size_t* in_avail, 00574 /* out */ size_t* out_avail); 00575 virtual EStatus Flush (char* out_buf, size_t out_size, 00576 /* out */ size_t* out_avail); 00577 virtual EStatus Finish (char* out_buf, size_t out_size, 00578 /* out */ size_t* out_avail); 00579 virtual EStatus End (void); 00580 00581 protected: 00582 /// Decompress block of data in the cache buffer. 00583 bool DecompressCache(void); 00584 00585 private: 00586 size_t m_BlockLen; ///< Length of the compressed data in the block 00587 string m_Cache; ///< Buffer to cache header. 00588 00589 // Parameters read from header (used for compression). 00590 // See fStreamFormat flag description. 00591 size_t m_HeaderLen; ///< Length of the header. 00592 unsigned int m_HeaderFlags; ///< Flags used for compression. 00593 }; 00594 00595 00596 00597 ////////////////////////////////////////////////////////////////////////////// 00598 /// 00599 /// CLZOStreamCompressor -- zlib based compression stream processor 00600 /// 00601 /// See util/compress/stream.hpp for details. 00602 /// @sa CCompressionStreamProcessor 00603 00604 class CLZOStreamCompressor 00605 : public CCompressionStreamProcessor 00606 { 00607 public: 00608 /// Constructor. 00609 CLZOStreamCompressor( 00610 CCompression::ELevel level = CCompression::eLevel_Default, 00611 streamsize in_bufsize = kCompressionDefaultBufSize, 00612 streamsize out_bufsize = kCompressionDefaultBufSize, 00613 size_t blocksize = kLZODefaultBlockSize, 00614 CCompression::TFlags flags = 0 00615 ) 00616 : CCompressionStreamProcessor( 00617 new CLZOCompressor(level, blocksize), 00618 eDelete, in_bufsize, out_bufsize) 00619 {} 00620 }; 00621 00622 00623 ///////////////////////////////////////////////////////////////////////////// 00624 /// 00625 /// CLZOStreamDecompressor -- zlib based decompression stream processor 00626 /// 00627 /// See util/compress/stream.hpp for details. 00628 /// @sa CCompressionStreamProcessor 00629 00630 class CLZOStreamDecompressor 00631 : public CCompressionStreamProcessor 00632 { 00633 public: 00634 /// Full constructor 00635 CLZOStreamDecompressor( 00636 streamsize in_bufsize, 00637 streamsize out_bufsize, 00638 size_t blocksize, 00639 CCompression::TFlags flags = 0 00640 ) 00641 : CCompressionStreamProcessor( 00642 new CLZODecompressor(blocksize, flags), 00643 eDelete, in_bufsize, out_bufsize) 00644 {} 00645 00646 /// Conventional constructor 00647 CLZOStreamDecompressor(CCompression::TFlags flags = 0) 00648 : CCompressionStreamProcessor( 00649 new CLZODecompressor(kLZODefaultBlockSize, flags), 00650 eDelete, kCompressionDefaultBufSize, kCompressionDefaultBufSize) 00651 {} 00652 }; 00653 00654 00655 END_NCBI_SCOPE 00656 00657 00658 /* @} */ 00659 00660 #endif /* HAVE_LIBLZO */ 00661 00662 #endif /* UTIL_COMPRESS__LZO__HPP */ 00663 00664
1.4.6
Modified on Wed Nov 19 07:46:04 2008 by modify_doxy.py rev. 117643