From 4386b9bc836f58bbccb360802148b33e99eed967 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Sat, 11 Dec 2004 23:06:34 +0000 Subject: [PATCH] add deflate compressing (simple, since we already use zlib) --- stepmania/src/RageFileDriverDeflate.cpp | 95 +++++++++++++++++++++++++ stepmania/src/RageFileDriverDeflate.h | 19 +++++ 2 files changed, 114 insertions(+) diff --git a/stepmania/src/RageFileDriverDeflate.cpp b/stepmania/src/RageFileDriverDeflate.cpp index 62115043db..19e82599de 100644 --- a/stepmania/src/RageFileDriverDeflate.cpp +++ b/stepmania/src/RageFileDriverDeflate.cpp @@ -181,6 +181,101 @@ int RageFileObjInflate::SeekInternal( int iPos ) return m_iFilePos; } +RageFileObjDeflate::RageFileObjDeflate( RageFileBasic *pFile ) +{ + m_pFile = pFile; + m_bFileOwned = false; + + m_pDeflate = new z_stream; + memset( m_pDeflate, 0, sizeof(z_stream) ); + + int err = deflateInit2( m_pDeflate, + 3, + Z_DEFLATED, + -15, // windowBits + 8, // memLevel + Z_DEFAULT_STRATEGY ); + + if( err == Z_MEM_ERROR ) + RageException::Throw( "inflateInit2( %i ): out of memory", -MAX_WBITS ); + if( err != Z_OK ) + LOG->Trace( "Huh? inflateInit2() err = %i", err ); + +} + +RageFileObjDeflate::~RageFileObjDeflate() +{ + FlushInternal(); + + if( m_bFileOwned ) + delete m_pFile; + + int err = deflateEnd( m_pDeflate ); + if( err != Z_OK ) + LOG->Trace( "Huh? deflateEnd() err = %i", err ); + + delete m_pDeflate; +} + +int RageFileObjDeflate::WriteInternal( const void *pBuffer, size_t iBytes ) +{ + m_pDeflate->next_in = (Bytef*) pBuffer; + m_pDeflate->avail_in = iBytes; + + while( m_pDeflate->avail_in > 0 ) + { + char buf[1024*4]; + m_pDeflate->next_out = (Bytef *) buf; + m_pDeflate->avail_out = sizeof(buf); + + int err = deflate( m_pDeflate, Z_NO_FLUSH ); + + if( err != Z_OK ) + FAIL_M( ssprintf("deflate: err %i", err) ); + + if( m_pDeflate->avail_out > 0 ) + { + int iRet = m_pFile->Write( buf, sizeof(buf)-m_pDeflate->avail_out ); + if( iRet == -1 ) + { + SetError( m_pFile->GetError() ); + return -1; + } + } + } + + return iBytes; +} + +int RageFileObjDeflate::FlushInternal() +{ + m_pDeflate->avail_in = 0; + + while( 1 ) + { + char buf[1024*4]; + m_pDeflate->next_out = (Bytef *) buf; + m_pDeflate->avail_out = sizeof(buf); + + int err = deflate( m_pDeflate, Z_FINISH ); + if( err != Z_OK && err != Z_STREAM_END ) + FAIL_M( ssprintf("deflate: err %i", err) ); + + if( m_pDeflate->avail_out > 0 ) + { + int iRet = m_pFile->Write( buf, sizeof(buf)-m_pDeflate->avail_out ); + if( iRet == -1 ) + { + SetError( m_pFile->GetError() ); + return -1; + } + } + + if( err == Z_STREAM_END ) + return 0; + } +} + /* * Copyright (c) 2003-2004 Glenn Maynard * All rights reserved. diff --git a/stepmania/src/RageFileDriverDeflate.h b/stepmania/src/RageFileDriverDeflate.h index ce5a114dfb..ea34821877 100644 --- a/stepmania/src/RageFileDriverDeflate.h +++ b/stepmania/src/RageFileDriverDeflate.h @@ -35,6 +35,25 @@ private: int decomp_buf_avail; }; +class RageFileObjDeflate: public RageFileObj +{ +public: + /* By default, pFile will not be freed. */ + RageFileObjDeflate( RageFileBasic *pOutput ); + ~RageFileObjDeflate(); + + int GetFileSize() const { return m_pFile->GetFileSize(); } + +private: + int ReadInternal( void *pBuffer, size_t iBytes ) { SetError( "Not implemented" ); return -1; } + int WriteInternal( const void *pBuffer, size_t iBytes ); + int FlushInternal(); + + RageFileBasic *m_pFile; + z_stream *m_pDeflate; + bool m_bFileOwned; +}; + #endif /*