opennurbs_compress.cpp
Go to the documentation of this file.
00001 /* $NoKeywords: $ */
00002 /*
00003 //
00004 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
00005 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
00006 // McNeel & Associates.
00007 //
00008 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
00009 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
00010 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
00011 //                              
00012 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
00013 //
00015 */
00016 
00017 #include "pcl/surface/3rdparty/opennurbs/opennurbs.h"
00018 
00019 struct ON_ZlibImplementation
00020 {
00021   z_stream m_strm;
00022   unsigned char m_zlib_out_buffer[16384];
00023 };
00024 
00025 ON_CompressStream::ON_CompressStream()
00026 : m_out_callback_function(0)
00027 , m_out_callback_context(0)
00028 , m_in_size(0)
00029 , m_out_size(0)
00030 , m_in_crc(0)
00031 , m_out_crc(0)
00032 , m_implementation(0)
00033 , m_reserved(0)
00034 {}
00035 
00036 
00037 ON_CompressStream::~ON_CompressStream()
00038 {
00039 
00040   if ( 0 != m_implementation )
00041   {
00042     onfree(m_implementation);
00043     m_implementation = 0;
00044   }
00045 }
00046 
00047 void ON_CompressStream::ErrorHandler()
00048 {
00049   // place holder for error handing
00050   ON_ERROR("ON_CompressStream error");
00051 }
00052 
00053 bool ON_CompressStream::Begin()
00054 {
00055   if ( 0 != m_implementation )
00056   {
00057     onfree(m_implementation);
00058     m_implementation = 0;
00059   }
00060 
00061   // zero these because the same instance of an 
00062   // ON_CompressStream class may be used multiple times.
00063   m_in_size = 0;
00064   m_out_size = 0;
00065   m_in_crc = 0;
00066   m_out_crc = 0;
00067 
00068   struct ON_ZlibImplementation* imp = (struct ON_ZlibImplementation*)onmalloc(sizeof(*imp));
00069   memset(&imp->m_strm,0,sizeof(imp->m_strm));
00070 
00071   if ( Z_OK != deflateInit( &imp->m_strm, Z_BEST_COMPRESSION ) )
00072   {
00073     onfree(imp);
00074     return false;
00075   }
00076 
00077   m_implementation = imp;
00078 
00079   return true;
00080 }
00081 
00082 
00083 bool ON_CompressStream::In( ON__UINT64 size, const void* uncompressed_buffer )
00084 {
00085   if ( size <= 0 )
00086     return true;
00087 
00088   if ( 0 == m_implementation )
00089   {
00090     ErrorHandler();
00091     return false;
00092   }
00093 
00094   if ( 0 == uncompressed_buffer )
00095   {
00096     ErrorHandler();
00097     return false;
00098   }
00099   
00100   struct ON_ZlibImplementation* imp = (struct ON_ZlibImplementation*)m_implementation;
00101   z_stream& strm = imp->m_strm;
00102   if ( 0 != strm.avail_in || 0 != strm.next_in )
00103   {
00104     // strm.avail_in is always zero when we leave an ON_CompressStream function.
00105     ErrorHandler();
00106     return false;
00107   }
00108 
00109   const ON__UINT32 sizeof_out_buffer = (ON__UINT32)(sizeof(imp->m_zlib_out_buffer));
00110   void* out_buffer = imp->m_zlib_out_buffer;
00111   int zrc = Z_OK;
00112   const ON__UINT64 max_sz = 0x7FFFFFF0;
00113   bool rc = false;
00114   ON__UINT32 deflate_output_count;
00115 
00116   // counter prevents infinte loops if there is a bug in zlib return codes.
00117   for( int counter = 512; counter > 0; counter-- )
00118   {
00119     // Call zlib's deflate function.  It can either process
00120     // more input from m_zlib.strm.next_in[], create more
00121     // compressed output in m_zlib.strm.next_out[], or do both.
00122 
00123     // provide storage for compressed stream output
00124     strm.next_out  = (z_Bytef*)out_buffer;
00125     strm.avail_out = sizeof_out_buffer;
00126 
00127     if ( strm.avail_in <= 0 )
00128     {
00129       if ( size <= 0 )
00130       {
00131         // finshed with uncompressed input
00132         break;
00133       }
00134       // submit a portion of uncompressed_buffer to zlib
00135       ON__UINT64 sz = (size > max_sz) ? max_sz : size;
00136       m_in_size += sz;
00137       m_in_crc = ON_CRC32(m_in_crc,(size_t)sz,uncompressed_buffer); // (size_t) cast is safe because sz <= max_sz = 0x7FFFFFF0
00138       strm.next_in = (z_Bytef*)uncompressed_buffer;
00139       strm.avail_in = (ON__UINT32)sz;
00140       uncompressed_buffer = ((const unsigned char*)uncompressed_buffer) + sz;
00141       size -= sz;
00142       counter = 512; // added input - reset the counter that detects stalls
00143     }
00144 
00145     // calculate compression
00146     ON__UINT32 avail_in0 = strm.avail_in;
00147     ON__UINT32 avail_out0 = strm.avail_out;
00148     zrc = z_deflate( &strm, Z_NO_FLUSH ); 
00149     if ( zrc < 0 ) 
00150     {
00151       // Something went haywire - bail out.
00152       ErrorHandler();
00153       rc = false;
00154       break;
00155     }
00156     if ( strm.avail_in < avail_in0 || strm.avail_out > avail_out0 )
00157     {
00158       // zlib did something
00159       rc = true; 
00160     }    
00161 
00162     deflate_output_count = sizeof_out_buffer - strm.avail_out;
00163     if ( deflate_output_count > 0 ) 
00164     {
00165       // The last call to deflate created compressed output.  
00166       // Send the output to compressed stream handler.
00167 
00168       // Calculate the updated crc and size before we call
00169       // the output handler because someday sombody will
00170       // decide it's a good idea to modify the values
00171       // in the buffer argument.
00172       ON__UINT32 out_crc1 = ON_CRC32( m_out_crc, deflate_output_count, out_buffer);
00173       ON__UINT64 out_size1 = m_out_size + deflate_output_count;
00174       
00175       rc = (0 != m_out_callback_function)
00176           ? m_out_callback_function( m_out_callback_context, deflate_output_count, out_buffer )
00177           : Out( m_out_callback_context, deflate_output_count, out_buffer );
00178       if ( !rc )
00179         break;
00180 
00181       // Update compressed stream crc and size
00182       m_out_crc = out_crc1;
00183       m_out_size = out_size1;
00184       counter = 512; // created output - reset counter that detects stalls
00185     }
00186 
00187     if ( size <= 0 && strm.avail_in <= 0 )
00188     {
00189       // no input left
00190       break;
00191     }
00192   }
00193 
00194   strm.avail_in = 0;
00195   strm.next_in = 0;
00196   strm.next_out  = 0;
00197   strm.avail_out = 0;
00198 
00199   return rc;
00200 }
00201 
00202 bool ON_CompressStream::End()
00203 {
00204   if ( 0 == m_implementation )
00205   {
00206     ErrorHandler();
00207     return false;
00208   }
00209   
00210   struct ON_ZlibImplementation* imp = (struct ON_ZlibImplementation*)m_implementation;
00211   z_stream& strm = imp->m_strm;
00212   if ( 0 != strm.avail_in || 0 != strm.next_in )
00213   {
00214     // strm.avail_in is always zero when we leave an ON_CompressStream function.
00215     ErrorHandler();
00216     return false;
00217   }
00218 
00219   const ON__UINT32 sizeof_out_buffer = (ON__UINT32)(sizeof(imp->m_zlib_out_buffer));
00220   void* out_buffer = imp->m_zlib_out_buffer;
00221   int zrc = Z_OK;
00222   bool rc = false;
00223   ON__UINT32 deflate_output_count;
00224 
00225   // counter prevents infinte loops if there is a bug in zlib return codes.
00226   for( int counter = 512; counter > 0; counter-- )
00227   {
00228     // provide storage for compressed stream output
00229     strm.avail_in = 0;
00230     strm.next_in = 0;
00231     strm.next_out  = (z_Bytef*)out_buffer;
00232     strm.avail_out = sizeof_out_buffer;
00233 
00234     // finish compression calculation
00235     zrc = z_deflate( &strm, Z_FINISH ); 
00236     if ( zrc < 0 ) 
00237     {
00238       // Something went haywire - bail out.
00239       ErrorHandler();
00240       rc = false;
00241       break;
00242     }
00243 
00244     deflate_output_count = sizeof_out_buffer - strm.avail_out;
00245     if ( deflate_output_count > 0 ) 
00246     {
00247       // The last call to deflate created compressed output.  
00248       // Send the output to compressed stream handler.
00249 
00250       // Calculate the updated crc and size before we call
00251       // the output handler because someday sombody will
00252       // decide it's a good idea to modify the values
00253       // in the buffer argument.
00254       ON__UINT32 compressed_crc1 = ON_CRC32( m_out_crc, deflate_output_count, out_buffer);
00255       ON__UINT64 compressed_size1 = m_out_size + ((ON__UINT64)deflate_output_count);
00256       
00257       rc = (0 != m_out_callback_function)
00258           ? m_out_callback_function( m_out_callback_context, deflate_output_count, out_buffer )
00259           : Out( m_out_callback_context, deflate_output_count, out_buffer );
00260       if ( !rc )
00261         break;
00262 
00263       // Update compressed stream crc and size
00264       m_out_crc = compressed_crc1;
00265       m_out_size = compressed_size1;
00266       counter = 512; // created output - reset counter that detects stalls
00267     }
00268 
00269     if ( Z_STREAM_END == zrc )
00270     {
00271       // no input left, all pending compressing is finished,
00272       // and all compressed output has been returned.
00273       rc = true;
00274       break;
00275     }
00276   }
00277 
00278   strm.avail_in = 0;
00279   strm.next_in = 0;
00280   strm.next_out  = 0;
00281   strm.avail_out = 0;
00282 
00283   deflateEnd(&strm);
00284 
00285   onfree(m_implementation);
00286   m_implementation = 0;
00287 
00288   return rc;
00289 }
00290 
00291 bool ON_CompressStream::Out( void*, ON__UINT32, const void* )
00292 {
00293   // default compressed stream handler does nothing.
00294   return true;
00295 }
00296 
00297 bool ON_CompressStream::SetCallback( 
00298     ON_StreamCallbackFunction out_callback_function,
00299     void* out_callback_context
00300     )
00301 {
00302   m_out_callback_function = out_callback_function;
00303   m_out_callback_context = out_callback_context;
00304   return true;
00305 }
00306 
00307 ON_StreamCallbackFunction ON_CompressStream::CallbackFunction() const
00308 {
00309   return m_out_callback_function;
00310 }
00311 
00312 void* ON_CompressStream::CallbackContext() const
00313 {
00314   return m_out_callback_context;
00315 }
00316 
00317 
00318 ON__UINT64 ON_CompressStream::InSize() const
00319 {
00320   return m_in_size;
00321 }
00322 
00323 ON__UINT64 ON_CompressStream::OutSize() const
00324 {
00325   return m_out_size;
00326 }
00327 
00328 ON__UINT32 ON_CompressStream::InCRC() const
00329 {
00330   return m_in_crc;
00331 }
00332 
00333 ON__UINT32 ON_CompressStream::OutCRC() const
00334 {
00335   return m_out_crc;
00336 }
00337 
00338 
00340 
00341 
00342 ON_UncompressStream::ON_UncompressStream()
00343 : m_out_callback_function(0)
00344 , m_out_callback_context(0)
00345 , m_in_size(0)
00346 , m_out_size(0)
00347 , m_in_crc(0)
00348 , m_out_crc(0)
00349 , m_implementation(0)
00350 , m_reserved(0)
00351 {}
00352 
00353 
00354 ON_UncompressStream::~ON_UncompressStream()
00355 {
00356 
00357   if ( 0 != m_implementation )
00358   {
00359     onfree(m_implementation);
00360     m_implementation = 0;
00361   }
00362 }
00363 
00364 void ON_UncompressStream::ErrorHandler()
00365 {
00366   // place holder for error handing
00367   ON_ERROR("ON_UncompressStream error");
00368 }
00369 
00370 bool ON_UncompressStream::Begin()
00371 {
00372   if ( 0 != m_implementation )
00373   {
00374     onfree(m_implementation);
00375     m_implementation = 0;
00376   }
00377 
00378   // zero these because the same instance of an 
00379   // ON_UncompressStream class may be used multiple times.
00380   m_in_size = 0;
00381   m_out_size = 0;
00382   m_in_crc = 0;
00383   m_out_crc = 0;
00384 
00385   struct ON_ZlibImplementation* imp = (struct ON_ZlibImplementation*)onmalloc(sizeof(*imp));
00386   memset(&imp->m_strm,0,sizeof(imp->m_strm));
00387 
00388   if ( Z_OK != inflateInit( &imp->m_strm ) )
00389   {
00390     onfree(imp);
00391     return false;
00392   }
00393 
00394   m_implementation = imp;
00395 
00396 
00397   return true;
00398 }
00399 
00400 
00401 bool ON_UncompressStream::In( ON__UINT64 size, const void* compressed_buffer )
00402 {
00403   if ( size <= 0 )
00404     return true;
00405 
00406   if ( 0 == m_implementation )
00407   {
00408     ErrorHandler();
00409     return false;
00410   }
00411 
00412   if ( 0 == compressed_buffer )
00413   {
00414     ErrorHandler();
00415     return false;
00416   }
00417   
00418   struct ON_ZlibImplementation* imp = (struct ON_ZlibImplementation*)m_implementation;
00419   z_stream& strm = imp->m_strm;
00420   if ( 0 != strm.avail_in || 0 != strm.next_in )
00421   {
00422     // strm.avail_in is always zero when we leave an ON_UncompressStream function.
00423     ErrorHandler();
00424     return false;
00425   }
00426 
00427   const ON__UINT32 sizeof_out_buffer = (ON__UINT32)(sizeof(imp->m_zlib_out_buffer));
00428   void* out_buffer = imp->m_zlib_out_buffer;
00429   int zrc = Z_OK;
00430   const ON__UINT64 max_sz = 0x7FFFFFF0;
00431   bool rc = false;
00432   ON__UINT32 inflate_output_count;
00433 
00434   // counter prevents infinte loops if there is a bug in zlib return codes.
00435   for( int counter = 512; counter > 0; counter-- )
00436   {
00437     // Call zlib's inflate function.  It can process
00438     // more compressed input from strm.next_in[], create more
00439     // uncompressed output in strm.next_out[], or do both.
00440 
00441     // provide storage for uncompressed stream output
00442     strm.next_out  = (z_Bytef*)out_buffer;
00443     strm.avail_out = sizeof_out_buffer;
00444 
00445     if ( strm.avail_in <= 0 )
00446     {
00447       if ( size <= 0 )
00448       {
00449         // finshed with compressed input
00450         break;
00451       }
00452       // submit a portion of compressed_buffer to zlib
00453       ON__UINT64 sz = (size > max_sz) ? max_sz : size;
00454       m_in_size += sz;
00455       m_in_crc = ON_CRC32(m_in_crc,(size_t)sz,compressed_buffer); // (size_t) cast is safe because sz <= max_sz = 0x7FFFFFF0
00456       strm.next_in = (z_Bytef*)compressed_buffer;
00457       strm.avail_in = (ON__UINT32)sz;
00458       compressed_buffer = ((const unsigned char*)compressed_buffer) + sz;
00459       size -= sz;
00460       counter = 512; // added input - reset the counter that detects stalls
00461     }
00462 
00463     // calculate compression
00464     ON__UINT32 avail_in0 = strm.avail_in;
00465     ON__UINT32 avail_out0 = strm.avail_out;
00466     zrc = z_inflate( &strm, Z_NO_FLUSH ); 
00467     if ( zrc < 0 ) 
00468     {
00469       // Something went haywire - bail out.
00470       ErrorHandler();
00471       rc = false;
00472       break;
00473     }
00474     if ( strm.avail_in < avail_in0 || strm.avail_out > avail_out0 )
00475     {
00476       // zlib did something
00477       rc = true; 
00478     }    
00479 
00480     inflate_output_count = sizeof_out_buffer - strm.avail_out;
00481     if ( inflate_output_count > 0 ) 
00482     {
00483       // The last call to inflate created uncompressed output.  
00484       // Send the output to the uncompressed stream handler.
00485 
00486       // Calculate the updated crc and size before we call
00487       // the output handler because someday sombody will
00488       // decide it's a good idea to modify the values
00489       // in the buffer argument.
00490       ON__UINT32 out_crc1 = ON_CRC32( m_out_crc, inflate_output_count, out_buffer);
00491       ON__UINT64 out_size1 = m_out_size + inflate_output_count;
00492       
00493       rc = (0 != m_out_callback_function)
00494           ? m_out_callback_function( m_out_callback_context, inflate_output_count, out_buffer )
00495           : Out( m_out_callback_context, inflate_output_count, out_buffer );
00496       if ( !rc )
00497         break;
00498 
00499       // Update compressed stream crc and size
00500       m_out_crc = out_crc1;
00501       m_out_size = out_size1;
00502       counter = 512; // created output - reset counter that detects stalls
00503     }
00504 
00505     if ( size <= 0 && strm.avail_in <= 0 )
00506     {
00507       // no input left
00508       break;
00509     }
00510   }
00511 
00512   strm.avail_in = 0;
00513   strm.next_in = 0;
00514   strm.next_out  = 0;
00515   strm.avail_out = 0;
00516 
00517   return rc;
00518 }
00519 
00520 bool ON_UncompressStream::End()
00521 {
00522   if ( 0 == m_implementation )
00523   {
00524     ErrorHandler();
00525     return false;
00526   }
00527   
00528   struct ON_ZlibImplementation* imp = (struct ON_ZlibImplementation*)m_implementation;
00529   z_stream& strm = imp->m_strm;
00530   if ( 0 != strm.avail_in || 0 != strm.next_in )
00531   {
00532     // strm.avail_in is always zero when we leave an ON_UncompressStream function.
00533     ErrorHandler();
00534     return false;
00535   }
00536 
00537   const ON__UINT32 sizeof_out_buffer = (ON__UINT32)(sizeof(imp->m_zlib_out_buffer));
00538   void* out_buffer = imp->m_zlib_out_buffer;
00539   int zrc = Z_OK;
00540   bool rc = false;
00541   ON__UINT32 inflate_output_count;
00542 
00543   // counter prevents infinte loops if there is a bug in zlib return codes.
00544   for( int counter = 512; counter > 0; counter-- )
00545   {
00546     // provide storage for compressed stream output
00547     strm.avail_in = 0;
00548     strm.next_in = 0;
00549     strm.next_out  = (z_Bytef*)out_buffer;
00550     strm.avail_out = sizeof_out_buffer;
00551 
00552     // finish compression calculation
00553     zrc = z_inflate( &strm, Z_FINISH ); 
00554     if ( zrc < 0 ) 
00555     {
00556       // Something went haywire - bail out.
00557       ErrorHandler();
00558       rc = false;
00559       break;
00560     }
00561 
00562     inflate_output_count = sizeof_out_buffer - strm.avail_out;
00563     if ( inflate_output_count > 0 ) 
00564     {
00565       // The last call to inflate created uncompressed output.  
00566       // Send the output to the uncompressed stream handler.
00567 
00568       // Calculate the updated crc and size before we call
00569       // the output handler because someday sombody will
00570       // decide it's a good idea to modify the values
00571       // in the buffer argument.
00572       ON__UINT32 out_crc1 = ON_CRC32( m_out_crc, inflate_output_count, out_buffer);
00573       ON__UINT64 out_size1 = m_out_size + inflate_output_count;
00574       
00575       rc = (0 != m_out_callback_function)
00576           ? m_out_callback_function( m_out_callback_context, inflate_output_count, out_buffer )
00577           : Out( m_out_callback_context, inflate_output_count, out_buffer );
00578       if ( !rc )
00579         break;
00580 
00581       // Update compressed stream crc and size
00582       m_out_crc = out_crc1;
00583       m_out_size = out_size1;
00584       counter = 512; // created output - reset counter that detects stalls
00585     }
00586 
00587     if ( Z_STREAM_END == zrc )
00588     {
00589       // no input left, all pending compressing is finished,
00590       // and all compressed output has been returned.
00591       rc = true;
00592       break;
00593     }
00594   }
00595 
00596   strm.avail_in = 0;
00597   strm.next_in = 0;
00598   strm.next_out  = 0;
00599   strm.avail_out = 0;
00600 
00601   inflateEnd(&strm);
00602 
00603   onfree(m_implementation);
00604   m_implementation = 0;
00605 
00606   return rc;
00607 }
00608 
00609 bool ON_UncompressStream::Out( void*, ON__UINT32, const void* )
00610 {
00611   // default uncompressed stream handler does nothing.
00612   return true;
00613 }
00614 
00615 bool ON_UncompressStream::SetCallback( 
00616     ON_StreamCallbackFunction out_callback_function,
00617     void* out_callback_context
00618     )
00619 {
00620   m_out_callback_function = out_callback_function;
00621   m_out_callback_context = out_callback_context;
00622   return true;
00623 }
00624 
00625 ON_StreamCallbackFunction ON_UncompressStream::CallbackFunction() const
00626 {
00627   return m_out_callback_function;
00628 }
00629 
00630 void* ON_UncompressStream::CallbackContext() const
00631 {
00632   return m_out_callback_context;
00633 }
00634 
00635 ON__UINT64 ON_UncompressStream::InSize() const
00636 {
00637   return m_in_size;
00638 }
00639 
00640 ON__UINT64 ON_UncompressStream::OutSize() const
00641 {
00642   return m_out_size;
00643 }
00644 
00645 ON__UINT32 ON_UncompressStream::InCRC() const
00646 {
00647   return m_in_crc;
00648 }
00649 
00650 ON__UINT32 ON_UncompressStream::OutCRC() const
00651 {
00652   return m_out_crc;
00653 }
00654 


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:27:00