Octane v1.01.20 - The Open Compression Toolkit for C++ http://octane.sourceforge.net/
Homepage | Main | Modules | Class Hierarchy | Compound List | File List | Compound Members | Related Pages

compressors/compressor.cpp

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 //---------------------------------------------------------------------------
00010 
00011 //---------------------------------------------------------------------------
00012 // application includes
00013 #include "compressor.hpp"
00014 #include "../utilityclasses/timer/timer.hpp"
00015 //---------------------------------------------------------------------------
00016 
00017 
00018 
00019 //---------------------------------------------------------------------------
00020 void OctaneCompressor::SetInfo(std::string compressorname, unsigned short int compressorguid)
00021 {
00022         // Set details (compressor name and guid) from file
00023         instantiatedname=compressorname;
00024         guid=compressorguid;
00025 }
00026 //---------------------------------------------------------------------------
00027 
00028 
00029 //---------------------------------------------------------------------------
00030 // COMPRESSOR PUBLIC API - COMPRESSING/DECOMPRESSING WRAPPERS (NOT VIRTUAL!)
00031 //  These methods just wrap the calls below inside some timing/stats gathering functions
00032 
00033 bool OctaneCompressor::Compress(bitreader &from, bitwriter &to, bool needtowriteheader, bool savedecompressstateinfo)
00034 {
00035         // just wrap the calls to derived classes
00036         bool bretv;
00037         OctaneTimer octanetimer;
00038         size_t fromstart,tostart;
00039 
00040         // do compression and measure it
00041         octanetimer.start();
00042         fromstart=from.tell_byte();
00043         tostart=to.tell_byte();
00044 
00045         if (needtowriteheader)
00046                 {
00047                 // save header - this is either a supershort GUID only (usually only 1 byte), or the complete stateinfo for the compressor
00048                 SaveCompressionHeader(to,savedecompressstateinfo);
00049                 }
00050 
00051         // do actual compression
00052         bretv=DoProtectedCompress(from,to);
00053 
00054         // align output bitwriter (this must be performed when we finish)
00055         to.align_byte();
00056 
00057         // finish measurements
00058         LastOperation_Compression_ExecutionTime=octanetimer.stop();
00059         Cumulative_Compression_ExecutionTime+=LastOperation_Compression_ExecutionTime;
00060         LastOperation_Compression_BytesRead=from.tell_byte()-fromstart;
00061         Cumulative_Compression_BytesRead+=LastOperation_Compression_BytesRead;
00062         LastOperation_Compression_BytesWritten=to.tell_byte()-tostart;
00063         Cumulative_Compression_BytesWritten+=LastOperation_Compression_BytesWritten;
00064         
00065         // update error counts
00066         if (!bretv)
00067                 {
00068                 ++Cumulative_ErrorCount;
00069                 ++LastOperation_ErrorCount;
00070                 }
00071 
00072         // return success
00073         return bretv;
00074 }
00075 
00076 
00077 bool OctaneCompressor::Decompress(bitreader &from, bitwriter &to, bool needtoreadheader)
00078 {
00079         // just wrap the calls to derived classes
00080         bool bretv;
00081         OctaneTimer octanetimer;
00082         size_t fromstart,tostart;
00083 
00084         // do decompression and measure it
00085         octanetimer.start();
00086         fromstart=from.tell_byte();
00087         tostart=to.tell_byte();
00088 
00089         if (needtoreadheader)
00090                 {
00091                 // this decompress could be called before the header is read, or after it.
00092                 // if the header is already read by caller, we wont try to re-read it here.
00093                 // if it hasn't been read yet, we can read it here, and it MUST match our current compressor.
00094                 // load header - this is either a supershort GUID only (usually only 1 byte), or the complete stateinfo for the compressor
00095                 bretv=LoadCompressionHeader(from);
00096                 }
00097 
00098         // do decompression
00099         bretv=DoProtectedDecompress(from,to);
00100         
00101         // align output bitwriter (this must be performed when we finish)
00102         to.align_byte();
00103 
00104         // finish measurements
00105         LastOperation_Decompression_ExecutionTime=octanetimer.stop();
00106         Cumulative_Decompression_ExecutionTime+=LastOperation_Decompression_ExecutionTime;
00107         LastOperation_Decompression_BytesRead=from.tell_byte()-fromstart;
00108         Cumulative_Decompression_BytesRead+=LastOperation_Decompression_BytesRead;
00109         LastOperation_Decompression_BytesWritten=to.tell_byte()-tostart;
00110         Cumulative_Decompression_BytesWritten+=LastOperation_Decompression_BytesWritten;
00111 
00112         // update error counts
00113         if (!bretv)
00114                 {
00115                 ++Cumulative_ErrorCount;
00116                 ++LastOperation_ErrorCount;
00117                 }
00118                 
00119         // return success
00120         return bretv;
00121 }
00122 //---------------------------------------------------------------------------
00123 
00124 
00125 //---------------------------------------------------------------------------
00126 bool OctaneCompressor::CreateSymbolsAndModelsUsingStream(bitreader &from)
00127 {
00128         // wrap call to save state and measure it
00129         bool bretv;
00130         OctaneTimer octanetimer;
00131 
00132         // do state save and measure it
00133         octanetimer.start();
00134         //
00135         bretv=DoProtectedCreateSymbolsAndModelsUsingStream(from);
00136         //
00137         LastOperation_State_ExecutionTime=octanetimer.stop();
00138 
00139         // update error counts
00140         if (!bretv)
00141                 {
00142                 ++Cumulative_ErrorCount;
00143                 ++LastOperation_ErrorCount;
00144                 }
00145 
00146         // return success
00147         return bretv;
00148 }
00149         
00150 
00151 bool OctaneCompressor::Save(bitwriter &to,bool fortempdecompressiononly)
00152 {
00153         // wrap call to save state and measure it
00154         bool bretv;
00155         size_t tostart;
00156         OctaneTimer octanetimer;
00157 
00158         // do state save and measure it
00159         octanetimer.start();
00160         tostart=to.tell_byte();
00161 
00162         // save compressor header (see OctaneCompressor::Save() for where this is written)
00163         string tempstring=GetClassName();
00164         to.put(tempstring);
00165         tempstring=GetInstantiatedName();
00166         to.put(tempstring);
00167         to.put(guid);
00168         
00169         // now call derived protected method to save state
00170         bretv=DoProtectedSaveState(to,fortempdecompressiononly);
00171 
00172         // measure result
00173         LastOperation_State_BytesWritten=to.tell_byte()-tostart;
00174         LastOperation_State_ExecutionTime=octanetimer.stop();
00175         
00176         // update error counts
00177         if (!bretv)
00178                 {
00179                 ++Cumulative_ErrorCount;
00180                 ++LastOperation_ErrorCount;
00181                 }
00182 
00183         // return success
00184         return bretv;
00185 }
00186 
00187 
00188 bool OctaneCompressor::Load(bitreader &from)
00189         {
00190         //  Normally the compressor manager loads the header of a saved file and dynamically instantiates a compressor,
00191         //   but we provide this function for manually calling load on an already instantiated compressor.
00192         //  It reads the header, verifies it is for proper class, and then calls LoadState().
00193         bool bretv;
00194 
00195         // read standard compressor header (see OctaneCompressor::Save() for where this is written)
00196         string compressorclassname;
00197         string compressorname;
00198         short int compressorguid;
00199         from.get(compressorclassname);
00200         from.get(compressorname);
00201         from.get(compressorguid);
00202         
00203         if (compressorclassname!=GetClassName())
00204                 {
00205                 cout << "Error: class name from file does not match compressor class name being read; load aborted."<<endl;
00206                 return false;
00207                 }
00208 
00209         // set name but not guid
00210         if (instantiatedname=="")
00211                 instantiatedname=compressorname;
00212 
00213         // now load state
00214         bretv=LoadState(from);
00215         return bretv;
00216         }
00217         
00218 
00219 bool OctaneCompressor::LoadState(bitreader &from)
00220 {
00221         bool bretv;
00222         size_t fromstart;
00223         OctaneTimer octanetimer;
00224 
00225         // do state load and measure it
00226         octanetimer.start();
00227         fromstart=from.tell_byte();
00228         //
00229         bretv=DoProtectedLoadState(from);
00230         //
00231         LastOperation_State_ExecutionTime=octanetimer.stop();
00232         LastOperation_State_BytesRead=from.tell_byte()-fromstart;
00233 
00234         // update error counts
00235         if (!bretv)
00236                 {
00237                 ++Cumulative_ErrorCount;
00238                 ++LastOperation_ErrorCount;
00239                 }
00240 
00241         // return success
00242         return bretv;
00243 }
00244 //---------------------------------------------------------------------------
00245 
00246 
00247 
00248 //---------------------------------------------------------------------------
00249 void OctaneCompressor::ResetStatistics()
00250 {
00251         // reset all statistics
00252         Cumulative_Compression_BytesRead=0;
00253         Cumulative_Decompression_BytesRead=0;
00254         Cumulative_Compression_BytesWritten=0;
00255         Cumulative_Decompression_BytesWritten=0;
00256         Cumulative_Compression_Bitrate=0;
00257         Cumulative_Decompression_Bitrate=0;
00258         Cumulative_Compression_Ratio=0;
00259         Cumulative_Decompression_Ratio=0;
00260         Cumulative_Compression_ExecutionTime=0;
00261         Cumulative_Decompression_ExecutionTime=0;
00262         Cumulative_ErrorCount=0;
00263         LastOperation_Compression_BytesRead=0;
00264         LastOperation_Decompression_BytesRead=0;
00265         LastOperation_Compression_BytesWritten=0;
00266         LastOperation_Decompression_BytesWritten=0;
00267         LastOperation_State_BytesRead=0;
00268         LastOperation_State_BytesWritten=0;
00269         LastOperation_Compression_Bitrate=0;
00270         LastOperation_Decompression_Bitrate=0;
00271         LastOperation_Compression_Ratio=0;
00272         LastOperation_Decompression_Ratio=0;
00273         LastOperation_Compression_ExecutionTime=0;
00274         LastOperation_Decompression_ExecutionTime=0;
00275         LastOperation_State_ExecutionTime=0;
00276         LastOperation_ErrorCount=0;
00277 }
00278 //---------------------------------------------------------------------------
00279 
00280 
00281 
00282 //---------------------------------------------------------------------------
00283 bool OctaneCompressor::SaveCompressionHeader(bitwriter &to, bool savedecompressstateinfo)
00284         {
00285         if (savedecompressstateinfo)
00286                 {
00287                 // save the state information  for the compressor prior to the data
00288                 // first write a special byte signifying that full state info follows
00289                 to.put_byte((unsigned char)254);
00290                 Save(to,true);
00291                 }
00292         else
00293                 {
00294                 // save only the GUID of the compressor
00295                 // if the GUID is valid, it should let receiver know which decompressor to use, or otherwise issue a warning
00296                 SaveGUID(to);
00297                 }
00298 
00299         // return success
00300         return true;
00301         }
00302 
00303 
00304 bool OctaneCompressor::LoadCompressionHeader(bitreader &from)
00305         {
00306         bool bretv;
00307         int retvguid;
00308 
00309         // load the guid (or -1 if the header is not a guid)
00310         retvguid=LoadGUID(from);
00311 
00312         if (retvguid!=-1)
00313                 {
00314                 // the header was just a guid, so we are done reading
00315                 // does it match our current compressor, if not give a warning and return false
00316                 if (guid!=retvguid)
00317                         {
00318                         cout << "WARNING: stored compressor guid ("<<retvguid<<") does not match current compressor ("<<guid<<")."<<endl;
00319                         return false;
00320                         }
00321                 return true;
00322                 }
00323         else
00324                 {
00325                 // load the full header information (just gets checked and thrown away)
00326                 bretv=Load(from);
00327                 return bretv;
00328                 }
00329 
00330         // return success
00331         return true;
00332         }
00333 
00334 
00336 bool OctaneCompressor::SaveGUID(bitwriter &to)
00337         {
00338         // save a short guid
00339         to.put_byte((unsigned char)guid);
00340         // return success
00341         return true;
00342         }
00343 
00344 
00346 int OctaneCompressor::LoadGUID(bitreader &from)
00347         {
00348         // load a short guid
00349         unsigned char c;
00350 
00351         // read first character
00352         c=from.get_byte();
00353         
00354         // special NONGUID character
00355         if (c==254)
00356                 return -1;
00357 
00358         return c;
00359         }
00360 //---------------------------------------------------------------------------
 
Generated on 20 May 2004 by doxygen 1.3.3