00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00015
00016
00017 #include "pcl/surface/3rdparty/opennurbs/opennurbs.h"
00018
00019 #if defined(ON_DLL_EXPORTS)
00020
00021
00022
00023
00024
00025 #define OPENNURBS_ZLIB_FILE_NAME "zlib.lib"
00026
00028
00029
00030
00031
00032
00033
00034 #define OPENNURBS_ZLIB_OUTPUT_ROOT_DIR "."
00035
00036
00037 #if defined(WIN64) && defined(_M_X64)
00038
00039
00040
00041 #if defined(NDEBUG)
00042
00043
00044 #define OPENNURBS_CONFIGURATION_DIR "x64/Release"
00045
00046 #else // _DEBUG
00047
00048
00049 #define OPENNURBS_CONFIGURATION_DIR "x64/Debug"
00050
00051 #endif // if NDEBUG else _DEBUG
00052
00053 #elif defined(WIN32) && defined(_M_IX86)
00054
00055
00056
00057 #if defined(NDEBUG)
00058
00059
00060 #define OPENNURBS_CONFIGURATION_DIR "Release"
00061
00062 #else // _DEBUG
00063
00064
00065 #define OPENNURBS_CONFIGURATION_DIR "Debug"
00066
00067 #endif // if NDEBUG else _DEBUG
00068
00069 #endif // if WIN64 else WIN32
00070
00071 #pragma comment(lib, "\"" OPENNURBS_ZLIB_OUTPUT_ROOT_DIR "/" OPENNURBS_CONFIGURATION_DIR "/" OPENNURBS_ZLIB_FILE_NAME "\"")
00072
00073 #endif // ON_DLL_EXPORTS
00074
00075
00076 bool ON_BinaryArchive::WriteCompressedBuffer(
00077 size_t sizeof__inbuffer,
00078 const void* inbuffer
00079 )
00080 {
00081 size_t compressed_size = 0;
00082 bool rc = false;
00083
00084 if ( !WriteMode() )
00085 return false;
00086 if ( sizeof__inbuffer > 0 && 0 == inbuffer )
00087 return false;
00088
00089
00090
00091
00092 if (!WriteSize(sizeof__inbuffer))
00093 return false;
00094 if ( 0 == sizeof__inbuffer )
00095 return true;
00096
00097
00098 const unsigned int buffer_crc = ON_CRC32( 0, sizeof__inbuffer, inbuffer );
00099 if (!WriteInt(buffer_crc))
00100 return false;
00101
00102 unsigned char method = (sizeof__inbuffer > 128) ? 1 : 0;
00103 if ( method ) {
00104 if ( !CompressionInit() ) {
00105 CompressionEnd();
00106 method = 0;
00107 }
00108 }
00109 if ( !WriteChar(method) )
00110 return false;
00111
00112 switch ( method )
00113 {
00114 case 0:
00115 rc = WriteByte(sizeof__inbuffer, inbuffer);
00116 if ( rc )
00117 {
00118 compressed_size = sizeof__inbuffer;
00119 }
00120 break;
00121
00122 case 1:
00123 compressed_size = WriteDeflate( sizeof__inbuffer, inbuffer );
00124 rc = ( compressed_size > 0 ) ? true : false;
00125 CompressionEnd();
00126 break;
00127 }
00128
00129
00130 return rc;
00131 }
00132
00133 bool ON_BinaryArchive::ReadCompressedBufferSize( size_t* sizeof__outbuffer )
00134 {
00135 return ReadSize(sizeof__outbuffer);
00136 }
00137
00138 bool ON_BinaryArchive::ReadCompressedBuffer(
00139 size_t sizeof__outbuffer,
00140 void* outbuffer,
00141 int* bFailedCRC
00142 )
00143 {
00144 bool rc = false;
00145 unsigned int buffer_crc0 = 0;
00146 unsigned int buffer_crc1 = 0;
00147 char method = 0;
00148
00149 if ( bFailedCRC)
00150 *bFailedCRC = false;
00151 if ( !ReadMode() )
00152 return false;
00153 if ( 0 == sizeof__outbuffer )
00154 return true;
00155 if ( 0 == outbuffer )
00156 return false;
00157
00158 if ( !ReadInt(&buffer_crc0) )
00159 return false;
00160
00161 if ( !ReadChar(&method) )
00162 return false;
00163
00164 if ( method != 0 && method != 1 )
00165 return false;
00166
00167 switch(method)
00168 {
00169 case 0:
00170 rc = ReadByte(sizeof__outbuffer, outbuffer);
00171 break;
00172 case 1:
00173 rc = CompressionInit();
00174 if (rc)
00175 rc = ReadInflate( sizeof__outbuffer, outbuffer );
00176 CompressionEnd();
00177 break;
00178 }
00179
00180 if (rc )
00181 {
00182 buffer_crc1 = ON_CRC32( 0, sizeof__outbuffer, outbuffer );
00183 if ( buffer_crc1 != buffer_crc0 )
00184 {
00185 ON_ERROR("ON_BinaryArchive::ReadCompressedBuffer() crc error");
00186 if ( bFailedCRC )
00187 *bFailedCRC = true;
00188 }
00189 }
00190
00191 return rc;
00192 }
00193
00194 size_t ON_BinaryArchive::WriteDeflate(
00195 size_t sizeof___inbuffer,
00196 const void* in___buffer
00197 )
00198 {
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 const size_t max_avail = 0x7FFFFFF0;
00257
00258
00259 bool rc = BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,0);
00260 if ( !rc )
00261 return false;
00262
00263 size_t out__count = 0;
00264 int zrc = Z_OK;
00265
00266 size_t my_avail_in = sizeof___inbuffer;
00267 unsigned char* my_next_in = (unsigned char*)in___buffer;
00268
00269 size_t d = my_avail_in;
00270 if ( d > max_avail )
00271 d = max_avail;
00272 m_zlib.strm.next_in = my_next_in;
00273 m_zlib.strm.avail_in = (unsigned int)d;
00274 my_avail_in -= d;
00275 my_next_in += d;
00276
00277 m_zlib.strm.next_out = m_zlib.buffer;
00278 m_zlib.strm.avail_out = m_zlib.sizeof_x_buffer;
00279
00280
00281 int counter = 512;
00282 int flush = Z_NO_FLUSH;
00283
00284 size_t deflate_output_count = 0;
00285
00286 while( rc && counter > 0 )
00287 {
00288
00289
00290
00291 if ( 0 == my_avail_in && 0 == m_zlib.strm.avail_in )
00292 {
00293
00294 flush = Z_FINISH;
00295 }
00296 zrc = z_deflate( &m_zlib.strm, flush );
00297 if ( zrc < 0 )
00298 {
00299
00300 ON_ERROR("ON_BinaryArchive::WriteDeflate - z_deflate failure");
00301 rc = false;
00302 break;
00303 }
00304
00305 deflate_output_count = m_zlib.sizeof_x_buffer - m_zlib.strm.avail_out;
00306 if ( deflate_output_count > 0 )
00307 {
00308
00309
00310 rc = WriteChar( deflate_output_count, m_zlib.buffer );
00311 if ( !rc )
00312 break;
00313 out__count += deflate_output_count;
00314 m_zlib.strm.next_out = m_zlib.buffer;
00315 m_zlib.strm.avail_out = m_zlib.sizeof_x_buffer;
00316 }
00317
00318 if ( Z_FINISH == flush && Z_STREAM_END == zrc )
00319 {
00320
00321
00322 break;
00323 }
00324
00325 if ( my_avail_in > 0 && m_zlib.strm.avail_in < max_avail )
00326 {
00327
00328
00329
00330 if ( 0 == m_zlib.strm.avail_in || 0 == m_zlib.strm.next_in )
00331 {
00332
00333
00334
00335 d = my_avail_in;
00336 if ( d > max_avail )
00337 d = max_avail;
00338 m_zlib.strm.next_in = my_next_in;
00339 m_zlib.strm.avail_in = (unsigned int)d;
00340 }
00341 else
00342 {
00343
00344
00345 d = max_avail - m_zlib.strm.avail_in;
00346 if ( d > my_avail_in )
00347 d = my_avail_in;
00348 m_zlib.strm.avail_in += (unsigned int)d;
00349 }
00350
00351 my_avail_in -= d;
00352 my_next_in += d;
00353 }
00354 else if ( 0 == deflate_output_count )
00355 {
00356
00357 counter--;
00358 }
00359
00360 if ( zrc != Z_OK )
00361 {
00362 break;
00363 }
00364 }
00365
00366 if ( !EndWrite3dmChunk() )
00367 {
00368 rc = false;
00369 }
00370
00371 if ( 0 == counter )
00372 {
00373 rc = false;
00374 }
00375
00376 return (rc ? out__count : 0);
00377 }
00378
00379
00380 bool ON_BinaryArchive::ReadInflate(
00381 size_t sizeof___outbuffer,
00382 void* out___buffer
00383 )
00384 {
00385 const size_t max_avail = 0x7FFFFFF0;
00386
00387 size_t sizeof__inbuffer = 0;
00388 void* in___buffer = 0;
00389 bool rc = false;
00390
00391
00392 bool bValidCompressedBuffer = false;
00393 {
00394 ON__UINT32 tcode = 0;
00395 ON__INT64 big_value = 0;
00396 rc = BeginRead3dmBigChunk(&tcode,&big_value );
00397 if (!rc)
00398 {
00399 if ( 0 != out___buffer && sizeof___outbuffer > 0 )
00400 memset(out___buffer,0,sizeof___outbuffer);
00401 return false;
00402 }
00403 if ( tcode == TCODE_ANONYMOUS_CHUNK
00404 && big_value > 4
00405 && sizeof___outbuffer > 0
00406 && 0 != out___buffer )
00407 {
00408
00409 sizeof__inbuffer = (size_t)(big_value-4);
00410 in___buffer = onmalloc(sizeof__inbuffer);
00411 if ( !in___buffer )
00412 {
00413 rc = false;
00414 }
00415 else
00416 {
00417 rc = ReadByte( sizeof__inbuffer, in___buffer );
00418 }
00419 }
00420 else
00421 {
00422
00423
00424 rc = false;
00425 }
00426 int c0 = m_bad_CRC_count;
00427 if ( !EndRead3dmChunk() )
00428 {
00429 rc = false;
00430 }
00431 bValidCompressedBuffer = ( m_bad_CRC_count > c0 )
00432 ? false
00433 : rc;
00434 }
00435
00436 if ( !bValidCompressedBuffer && 0 != out___buffer && sizeof___outbuffer > 0 )
00437 {
00438
00439
00440 memset(out___buffer,0,sizeof___outbuffer);
00441 }
00442
00443 if ( !rc )
00444 {
00445 if ( in___buffer )
00446 {
00447 onfree(in___buffer);
00448 in___buffer = 0;
00449 }
00450 return false;
00451 }
00452
00453 int zrc = -1;
00454
00455
00456 unsigned char* my_next_in = (unsigned char*)in___buffer;
00457 size_t my_avail_in = sizeof__inbuffer;
00458
00459 size_t d = my_avail_in;
00460 if ( d > max_avail )
00461 d = max_avail;
00462 m_zlib.strm.next_in = my_next_in;
00463 m_zlib.strm.avail_in = (unsigned int)d;
00464 my_next_in += d;
00465 my_avail_in -= d;
00466
00467
00468 unsigned char* my_next_out = (unsigned char*)out___buffer;
00469 size_t my_avail_out = sizeof___outbuffer;
00470
00471 d = my_avail_out;
00472 if ( d > max_avail )
00473 d = max_avail;
00474 m_zlib.strm.next_out = my_next_out;
00475 m_zlib.strm.avail_out = (unsigned int)d;
00476 my_next_out += d;
00477 my_avail_out -= d;
00478
00479
00480
00481 int counter = 512;
00482 int flush = Z_NO_FLUSH;
00483
00484 while ( rc && counter > 0 )
00485 {
00486
00487
00488
00489 if ( 0 == my_avail_in && 0 == m_zlib.strm.avail_in )
00490 {
00491
00492 flush = Z_FINISH;
00493 }
00494 zrc = z_inflate( &m_zlib.strm, flush );
00495 if ( zrc < 0 )
00496 {
00497
00498 ON_ERROR("ON_BinaryArchive::ReadInflate - z_inflate failure");
00499 rc = false;
00500 break;
00501 }
00502
00503 if ( Z_FINISH == flush && Z_STREAM_END == zrc )
00504 {
00505
00506
00507 break;
00508 }
00509
00510 d = 0;
00511 if ( my_avail_in > 0 && m_zlib.strm.avail_in < max_avail )
00512 {
00513 if ( 0 == m_zlib.strm.avail_in || 0 == m_zlib.strm.next_in )
00514 {
00515
00516
00517
00518 d = my_avail_in;
00519 if ( d > max_avail )
00520 d = max_avail;
00521 m_zlib.strm.next_in = my_next_in;
00522 m_zlib.strm.avail_in = (unsigned int)d;
00523 }
00524 else
00525 {
00526
00527
00528 d = max_avail - m_zlib.strm.avail_in;
00529 if ( d > my_avail_in )
00530 d = my_avail_in;
00531 m_zlib.strm.avail_in += (unsigned int)d;
00532 }
00533 my_next_in += d;
00534 my_avail_in -= d;
00535 }
00536
00537 if ( my_avail_out > 0 && m_zlib.strm.avail_out < max_avail )
00538 {
00539
00540 if ( 0 == m_zlib.strm.avail_out || 0 == m_zlib.strm.next_out )
00541 {
00542 d = my_avail_out;
00543 if ( d > max_avail )
00544 d = max_avail;
00545 m_zlib.strm.next_out = my_next_out;
00546 m_zlib.strm.avail_out = (unsigned int)d;
00547 }
00548 else
00549 {
00550 d = max_avail - m_zlib.strm.avail_out;
00551 if ( d > my_avail_out )
00552 d = my_avail_out;
00553 m_zlib.strm.avail_out += ((unsigned int)d);
00554 }
00555 my_next_out += d;
00556 my_avail_out -= d;
00557 }
00558 else if ( 0 == d )
00559 {
00560
00561 counter--;
00562 }
00563 }
00564
00565 if (in___buffer )
00566 {
00567 onfree(in___buffer);
00568 in___buffer = 0;
00569 }
00570
00571 if ( 0 == counter )
00572 {
00573 rc = false;
00574 }
00575
00576 return rc;
00577 }
00578
00579 bool ON_BinaryArchive::CompressionInit()
00580 {
00581
00582 bool rc = false;
00583 if ( WriteMode() ) {
00584 rc = ( m_zlib.mode == ON::write ) ? true : false;
00585 if ( !rc ) {
00586 CompressionEnd();
00587 if ( Z_OK == deflateInit( &m_zlib.strm, Z_BEST_COMPRESSION ) ) {
00588 m_zlib.mode = ON::write;
00589 rc = true;
00590 }
00591 else {
00592 memset(&m_zlib.strm,0,sizeof(m_zlib.strm));
00593 }
00594 }
00595 }
00596 else if ( ReadMode() ) {
00597 rc = ( m_zlib.mode == ON::read ) ? true : false;
00598 if ( !rc ) {
00599 CompressionEnd();
00600 if ( Z_OK == inflateInit( &m_zlib.strm ) ) {
00601 m_zlib.mode = ON::read;
00602 rc = true;
00603 }
00604 else {
00605 memset(&m_zlib.strm,0,sizeof(m_zlib.strm));
00606 }
00607 }
00608 }
00609 else {
00610 CompressionEnd();
00611 }
00612 return rc;
00613 }
00614
00615 void ON_BinaryArchive::CompressionEnd()
00616 {
00617
00618 switch ( m_zlib.mode ) {
00619 case ON::read:
00620 case ON::read3dm:
00621 inflateEnd(&m_zlib.strm);
00622 break;
00623 case ON::write:
00624 case ON::write3dm:
00625 deflateEnd(&m_zlib.strm);
00626 break;
00627 default:
00628 break;
00629 }
00630 memset(&m_zlib.strm,0,sizeof(m_zlib.strm));
00631 m_zlib.mode = ON::unknown_archive_mode;
00632 }
00633
00634
00635
00636 struct ON_CompressedBufferHelper
00637 {
00638 int action;
00639 enum
00640 {
00641 sizeof_x_buffer = 16384
00642 };
00643 unsigned char buffer[sizeof_x_buffer];
00644 z_stream strm;
00645 size_t m_buffer_compressed_capacity;
00646 };
00647
00648 ON_CompressedBuffer::ON_CompressedBuffer()
00649 : m_sizeof_uncompressed(0),
00650 m_sizeof_compressed(0),
00651 m_crc_uncompressed(0),
00652 m_crc_compressed(0),
00653 m_method(0),
00654 m_sizeof_element(0),
00655 m_buffer_compressed_capacity(0),
00656 m_buffer_compressed(0)
00657 {
00658 }
00659
00660 ON_CompressedBuffer::~ON_CompressedBuffer()
00661 {
00662 Destroy();
00663 }
00664
00665 ON_CompressedBuffer::ON_CompressedBuffer(const ON_CompressedBuffer& src)
00666 : m_sizeof_uncompressed(0),
00667 m_sizeof_compressed(0),
00668 m_crc_uncompressed(0),
00669 m_crc_compressed(0),
00670 m_method(0),
00671 m_sizeof_element(0),
00672 m_buffer_compressed_capacity(0),
00673 m_buffer_compressed(0)
00674 {
00675 *this = src;
00676 }
00677
00678 ON_CompressedBuffer& ON_CompressedBuffer::operator=(const ON_CompressedBuffer& src)
00679 {
00680 if ( this != &src )
00681 {
00682 Destroy();
00683 if( src.m_buffer_compressed && src.m_sizeof_compressed > 0 )
00684 {
00685 m_sizeof_uncompressed = src.m_sizeof_uncompressed;
00686 m_sizeof_compressed = src.m_sizeof_compressed;
00687 m_crc_uncompressed = src.m_crc_uncompressed;
00688 m_crc_compressed = src.m_crc_compressed;
00689 m_method = src.m_method;
00690 m_sizeof_element = src.m_sizeof_element;
00691
00692 m_buffer_compressed = onmalloc(m_sizeof_compressed);
00693 if( m_buffer_compressed )
00694 {
00695 m_buffer_compressed_capacity = m_sizeof_compressed;
00696 memcpy(m_buffer_compressed,src.m_buffer_compressed,m_sizeof_compressed);
00697 }
00698 }
00699 }
00700 return *this;
00701 }
00702
00703 bool ON_CompressedBuffer::Write( ON_BinaryArchive& binary_archive ) const
00704 {
00705 bool rc = binary_archive.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,0);
00706 if ( !rc )
00707 return false;
00708
00709 for(;;)
00710 {
00711 rc = binary_archive.WriteSize(m_sizeof_uncompressed);
00712 if (!rc)
00713 break;
00714 rc = binary_archive.WriteSize((m_buffer_compressed && m_sizeof_compressed>0) ? m_sizeof_compressed : 0);
00715 if (!rc)
00716 break;
00717 rc = binary_archive.WriteInt(m_crc_uncompressed);
00718 if (!rc)
00719 break;
00720 rc = binary_archive.WriteInt(m_crc_compressed);
00721 if (!rc)
00722 break;
00723 rc = binary_archive.WriteInt(m_method);
00724 if (!rc)
00725 break;
00726 rc = binary_archive.WriteInt(m_sizeof_element);
00727 if (!rc)
00728 break;
00729 if ( m_buffer_compressed && m_sizeof_compressed > 0 )
00730 {
00731 rc = binary_archive.WriteByte(m_sizeof_compressed,m_buffer_compressed);
00732 if (!rc)
00733 break;
00734 }
00735 break;
00736 }
00737
00738 if ( !binary_archive.EndWrite3dmChunk() )
00739 rc = false;
00740
00741 return rc;
00742 }
00743
00744 bool ON_CompressedBuffer::Read( ON_BinaryArchive& binary_archive )
00745 {
00746 int major_version = 0;
00747 int minor_version = 0;
00748 bool rc = binary_archive.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&major_version,&minor_version);
00749 if ( !rc )
00750 return false;
00751
00752 for(;;)
00753 {
00754 rc = ( 1 == major_version );
00755 if ( !rc )
00756 break;
00757 rc = binary_archive.ReadSize(&m_sizeof_uncompressed);
00758 if (!rc)
00759 break;
00760 rc = binary_archive.ReadSize(&m_sizeof_compressed);
00761 if (!rc)
00762 break;
00763 rc = binary_archive.ReadInt(&m_crc_uncompressed);
00764 if (!rc)
00765 break;
00766 rc = binary_archive.ReadInt(&m_crc_compressed);
00767 if (!rc)
00768 break;
00769 rc = binary_archive.ReadInt(&m_method);
00770 if (!rc)
00771 break;
00772 rc = binary_archive.ReadInt(&m_sizeof_element);
00773 if (!rc)
00774 break;
00775 if ( m_sizeof_compressed > 0 )
00776 {
00777 m_buffer_compressed = onmalloc(m_sizeof_compressed);
00778 if ( m_buffer_compressed )
00779 {
00780 m_buffer_compressed_capacity = m_sizeof_compressed;
00781 rc = binary_archive.ReadByte(m_sizeof_compressed,m_buffer_compressed);
00782 }
00783 else
00784 {
00785 m_sizeof_compressed =0;
00786 }
00787 if (!rc)
00788 break;
00789 }
00790
00791 break;
00792 }
00793
00794 if ( !binary_archive.EndRead3dmChunk() )
00795 rc = false;
00796
00797 return rc;
00798 }
00799
00800 void ON_CompressedBuffer::Destroy()
00801 {
00802 if ( m_buffer_compressed )
00803 onfree(m_buffer_compressed);
00804
00805 m_sizeof_uncompressed = 0;
00806 m_sizeof_compressed = 0;
00807 m_crc_uncompressed = 0;
00808 m_crc_compressed = 0;
00809 m_method = 0;
00810 m_sizeof_element = 0;
00811 m_buffer_compressed = 0;
00812 m_buffer_compressed_capacity = 0;
00813 }
00814
00815 bool ON_CompressedBuffer::Compress(
00816 size_t sizeof__inbuffer,
00817 const void* inbuffer,
00818 int sizeof_element
00819 )
00820 {
00821 Destroy();
00822
00823
00824 bool rc = false;
00825
00826 if ( sizeof__inbuffer > 0 && 0 == inbuffer )
00827 return false;
00828
00829 if ( 0 == sizeof__inbuffer )
00830 return true;
00831
00832
00833 m_sizeof_uncompressed = sizeof__inbuffer;
00834
00835 ON_CompressedBufferHelper helper;
00836 memset(&helper,0,sizeof(helper));
00837 helper.action = 1;
00838
00839 bool bToggleByteOrder = false;
00840 switch(sizeof_element)
00841 {
00842 case 2:
00843 case 4:
00844 case 8:
00845 if ( 0 == (sizeof__inbuffer%sizeof_element) )
00846 {
00847 m_sizeof_element = sizeof_element;
00848 bToggleByteOrder = (ON::big_endian == ON::Endian());
00849 }
00850 break;
00851 };
00852
00853 if ( bToggleByteOrder )
00854 {
00855 ON_BinaryFile::ToggleByteOrder(
00856 (int)(sizeof__inbuffer/m_sizeof_element),
00857 m_sizeof_element,
00858 inbuffer,
00859 (void*)inbuffer
00860 );
00861 }
00862
00863 m_method = (sizeof__inbuffer > 128) ? 1 : 0;
00864 if ( m_method )
00865 {
00866 if ( !CompressionInit(&helper) )
00867 {
00868 CompressionEnd(&helper);
00869 m_method = 0;
00870 }
00871 else
00872 {
00873 m_buffer_compressed = onmalloc(sizeof__inbuffer/4);
00874 size_t sizeof_compressed = DeflateHelper( &helper, sizeof__inbuffer, inbuffer );
00875 CompressionEnd(&helper);
00876 if ( sizeof_compressed > 0 && sizeof_compressed == m_sizeof_compressed )
00877 {
00878 rc = true;
00879 if ( 2*m_buffer_compressed_capacity > 3*m_sizeof_compressed )
00880 {
00881
00882 m_buffer_compressed_capacity = m_sizeof_compressed;
00883 m_buffer_compressed = onrealloc(m_buffer_compressed,m_buffer_compressed_capacity);
00884 }
00885 }
00886 else
00887 {
00888 Destroy();
00889 m_method = 0;
00890 }
00891 }
00892 }
00893
00894 if ( 0 == m_method )
00895 {
00896
00897 m_buffer_compressed = onmalloc(sizeof__inbuffer);
00898 if ( m_buffer_compressed )
00899 {
00900 m_sizeof_compressed = sizeof__inbuffer;
00901 m_buffer_compressed_capacity = sizeof__inbuffer;
00902 memcpy(m_buffer_compressed,inbuffer,sizeof__inbuffer);
00903 rc = true;
00904 }
00905 }
00906
00907 if ( bToggleByteOrder )
00908 {
00909 ON_BinaryFile::ToggleByteOrder(
00910 (int)(sizeof__inbuffer/m_sizeof_element),
00911 m_sizeof_element,
00912 inbuffer,
00913 (void*)inbuffer
00914 );
00915 }
00916
00917 if (rc)
00918 {
00919 m_crc_uncompressed = ON_CRC32( 0, sizeof__inbuffer, inbuffer );
00920 m_crc_compressed = ON_CRC32( 0, m_sizeof_compressed, m_buffer_compressed );
00921 }
00922
00923 return rc;
00924 }
00925
00926 bool ON_CompressedBuffer::Uncompress(
00927 void* outbuffer,
00928 int* bFailedCRC
00929 ) const
00930 {
00931 bool rc = false;
00932
00933 if ( bFailedCRC)
00934 *bFailedCRC = false;
00935 if ( 0 == m_sizeof_uncompressed )
00936 return true;
00937 if ( 0 == outbuffer )
00938 return false;
00939
00940 if ( m_method != 0 && m_method != 1 )
00941 return false;
00942
00943 ON__UINT32 compressed_crc = ON_CRC32( 0, m_sizeof_compressed, m_buffer_compressed );
00944 if ( compressed_crc != m_crc_compressed )
00945 {
00946
00947
00948
00949 memset(outbuffer,0,m_sizeof_uncompressed);
00950 if ( bFailedCRC)
00951 *bFailedCRC = false;
00952 }
00953
00954 switch(m_method)
00955 {
00956 case 0:
00957 if ( m_buffer_compressed
00958 && m_sizeof_uncompressed == m_sizeof_compressed
00959 )
00960 {
00961 memcpy(outbuffer,m_buffer_compressed,m_sizeof_uncompressed);
00962 rc = true;
00963 }
00964 break;
00965
00966 case 1:
00967 {
00968 ON_CompressedBufferHelper helper;
00969 memset(&helper,0,sizeof(helper));
00970 helper.action = 2;
00971 rc = CompressionInit(&helper);
00972 if (rc)
00973 {
00974 rc = InflateHelper( &helper, m_sizeof_uncompressed, outbuffer );
00975 CompressionEnd(&helper);
00976 }
00977 }
00978 break;
00979 }
00980
00981 switch(m_sizeof_element)
00982 {
00983 case 2:
00984 case 4:
00985 case 8:
00986 if ( 0 == (m_sizeof_uncompressed%m_sizeof_element) )
00987 {
00988 if ( ON::big_endian == ON::Endian() )
00989 {
00990 ON_BinaryFile::ToggleByteOrder(
00991 (int)(m_sizeof_uncompressed/m_sizeof_element),
00992 m_sizeof_element,
00993 outbuffer,
00994 outbuffer
00995 );
00996 }
00997 }
00998 break;
00999 };
01000
01001
01002 if (rc )
01003 {
01004 ON__UINT32 uncompressed_crc = ON_CRC32( 0, m_sizeof_uncompressed, outbuffer );
01005 if ( uncompressed_crc != m_crc_uncompressed )
01006 {
01007 ON_ERROR("ON_CompressedBuffer::Uncompress() crc error");
01008 if ( bFailedCRC )
01009 *bFailedCRC = true;
01010 }
01011 }
01012
01013 return rc;
01014 }
01015
01016 bool ON_CompressedBuffer::WriteChar(
01017 size_t count, const void* buffer
01018 )
01019 {
01020 bool rc = true;
01021 if ( count > 0 && buffer )
01022 {
01023 if ( count + m_sizeof_compressed > m_buffer_compressed_capacity )
01024 {
01025 size_t delta = count + m_sizeof_compressed - m_buffer_compressed_capacity;
01026 if ( delta < 2048 )
01027 delta = 2048;
01028 if ( delta < m_buffer_compressed_capacity/4 )
01029 delta = m_buffer_compressed_capacity/4;
01030 m_buffer_compressed_capacity += delta;
01031 m_buffer_compressed = onrealloc(m_buffer_compressed,m_buffer_compressed_capacity);
01032 if ( !m_buffer_compressed )
01033 {
01034 m_buffer_compressed_capacity = 0;
01035 m_sizeof_compressed = 0;
01036 return false;
01037 }
01038 }
01039 memcpy(((char*)m_buffer_compressed)+m_sizeof_compressed,buffer,count);
01040 m_sizeof_compressed += count;
01041 }
01042 else
01043 {
01044 rc = (0 == count);
01045 }
01046 return rc;
01047 }
01048
01049
01050 size_t ON_CompressedBuffer::DeflateHelper(
01051 ON_CompressedBufferHelper* helper,
01052 size_t sizeof___inbuffer,
01053 const void* in___buffer
01054 )
01055 {
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113 const size_t max_avail = 0x7FFFFFF0;
01114
01115
01116 bool rc = true;
01117
01118 size_t out__count = 0;
01119 int zrc = Z_OK;
01120
01121 size_t my_avail_in = sizeof___inbuffer;
01122 unsigned char* my_next_in = (unsigned char*)in___buffer;
01123
01124 size_t d = my_avail_in;
01125 if ( d > max_avail )
01126 d = max_avail;
01127
01128 ON_CompressedBufferHelper& m_zlib = *helper;
01129
01130 m_zlib.strm.next_in = my_next_in;
01131 m_zlib.strm.avail_in = (unsigned int)d;
01132 my_avail_in -= d;
01133 my_next_in += d;
01134
01135 m_zlib.strm.next_out = m_zlib.buffer;
01136 m_zlib.strm.avail_out = m_zlib.sizeof_x_buffer;
01137
01138
01139 int counter = 512;
01140 int flush = Z_NO_FLUSH;
01141
01142 size_t deflate_output_count = 0;
01143
01144 while( rc && counter > 0 )
01145 {
01146
01147
01148
01149 if ( 0 == my_avail_in && 0 == m_zlib.strm.avail_in )
01150 {
01151
01152 flush = Z_FINISH;
01153 }
01154 zrc = z_deflate( &m_zlib.strm, flush );
01155 if ( zrc < 0 )
01156 {
01157
01158 ON_ERROR("ON_CompressedBuffer::DeflateHelper - z_deflate failure");
01159 rc = false;
01160 break;
01161 }
01162
01163 deflate_output_count = m_zlib.sizeof_x_buffer - m_zlib.strm.avail_out;
01164 if ( deflate_output_count > 0 )
01165 {
01166
01167
01168 rc = WriteChar( deflate_output_count, m_zlib.buffer );
01169 if ( !rc )
01170 break;
01171 out__count += deflate_output_count;
01172 m_zlib.strm.next_out = m_zlib.buffer;
01173 m_zlib.strm.avail_out = m_zlib.sizeof_x_buffer;
01174 }
01175
01176 if ( Z_FINISH == flush && Z_STREAM_END == zrc )
01177 {
01178
01179
01180 break;
01181 }
01182
01183 if ( my_avail_in > 0 && m_zlib.strm.avail_in < max_avail )
01184 {
01185
01186
01187
01188 if ( 0 == m_zlib.strm.avail_in || 0 == m_zlib.strm.next_in )
01189 {
01190
01191
01192
01193 d = my_avail_in;
01194 if ( d > max_avail )
01195 d = max_avail;
01196 m_zlib.strm.next_in = my_next_in;
01197 m_zlib.strm.avail_in = (unsigned int)d;
01198 }
01199 else
01200 {
01201
01202
01203 d = max_avail - m_zlib.strm.avail_in;
01204 if ( d > my_avail_in )
01205 d = my_avail_in;
01206 m_zlib.strm.avail_in += (unsigned int)d;
01207 }
01208
01209 my_avail_in -= d;
01210 my_next_in += d;
01211 }
01212 else if ( 0 == deflate_output_count )
01213 {
01214
01215 counter--;
01216 }
01217
01218 if ( zrc != Z_OK )
01219 {
01220 break;
01221 }
01222 }
01223
01224 if ( 0 == counter )
01225 {
01226 rc = false;
01227 }
01228
01229 return (rc ? out__count : 0);
01230 }
01231
01232
01233 bool ON_CompressedBuffer::InflateHelper(
01234 ON_CompressedBufferHelper* helper,
01235 size_t sizeof___outbuffer,
01236 void* out___buffer
01237 ) const
01238 {
01239 const size_t max_avail = 0x7FFFFFF0;
01240
01241 bool rc = true;
01242
01243 int zrc = -1;
01244
01245
01246 unsigned char* my_next_in = (unsigned char*)m_buffer_compressed;
01247 size_t my_avail_in = m_sizeof_compressed;
01248
01249 size_t d = my_avail_in;
01250 if ( d > max_avail )
01251 d = max_avail;
01252
01253 struct ON_CompressedBufferHelper& m_zlib = *helper;
01254
01255 m_zlib.strm.next_in = my_next_in;
01256 m_zlib.strm.avail_in = (unsigned int)d;
01257 my_next_in += d;
01258 my_avail_in -= d;
01259
01260
01261 unsigned char* my_next_out = (unsigned char*)out___buffer;
01262 size_t my_avail_out = sizeof___outbuffer;
01263
01264 d = my_avail_out;
01265 if ( d > max_avail )
01266 d = max_avail;
01267 m_zlib.strm.next_out = my_next_out;
01268 m_zlib.strm.avail_out = (unsigned int)d;
01269 my_next_out += d;
01270 my_avail_out -= d;
01271
01272
01273
01274 int counter = 512;
01275 int flush = Z_NO_FLUSH;
01276
01277 while ( rc && counter > 0 )
01278 {
01279
01280
01281
01282 if ( 0 == my_avail_in && 0 == m_zlib.strm.avail_in )
01283 {
01284
01285 flush = Z_FINISH;
01286 }
01287 zrc = z_inflate( &m_zlib.strm, flush );
01288 if ( zrc < 0 )
01289 {
01290
01291 ON_ERROR("ON_CompressedBuffer::InflateHelper - z_inflate failure");
01292 rc = false;
01293 break;
01294 }
01295
01296 if ( Z_FINISH == flush && Z_STREAM_END == zrc )
01297 {
01298
01299
01300 break;
01301 }
01302
01303 d = 0;
01304 if ( my_avail_in > 0 && m_zlib.strm.avail_in < max_avail )
01305 {
01306 if ( 0 == m_zlib.strm.avail_in || 0 == m_zlib.strm.next_in )
01307 {
01308
01309
01310
01311 d = my_avail_in;
01312 if ( d > max_avail )
01313 d = max_avail;
01314 m_zlib.strm.next_in = my_next_in;
01315 m_zlib.strm.avail_in = (unsigned int)d;
01316 }
01317 else
01318 {
01319
01320
01321 d = max_avail - m_zlib.strm.avail_in;
01322 if ( d > my_avail_in )
01323 d = my_avail_in;
01324 m_zlib.strm.avail_in += (unsigned int)d;
01325 }
01326 my_next_in += d;
01327 my_avail_in -= d;
01328 }
01329
01330 if ( my_avail_out > 0 && m_zlib.strm.avail_out < max_avail )
01331 {
01332
01333 if ( 0 == m_zlib.strm.avail_out || 0 == m_zlib.strm.next_out )
01334 {
01335 d = my_avail_out;
01336 if ( d > max_avail )
01337 d = max_avail;
01338 m_zlib.strm.next_out = my_next_out;
01339 m_zlib.strm.avail_out = (unsigned int)d;
01340 }
01341 else
01342 {
01343 d = max_avail - m_zlib.strm.avail_out;
01344 if ( d > my_avail_out )
01345 d = my_avail_out;
01346 m_zlib.strm.avail_out += ((unsigned int)d);
01347 }
01348 my_next_out += d;
01349 my_avail_out -= d;
01350 }
01351 else if ( 0 == d )
01352 {
01353
01354 counter--;
01355 }
01356 }
01357
01358 if ( 0 == counter )
01359 {
01360 rc = false;
01361 }
01362
01363 return rc;
01364 }
01365
01366 bool ON_CompressedBuffer::CompressionInit( struct ON_CompressedBufferHelper* helper ) const
01367 {
01368 bool rc = false;
01369
01370 if ( helper )
01371 {
01372
01373 if ( 1 == helper->action )
01374 {
01375
01376 if ( Z_OK == deflateInit( &helper->strm, Z_BEST_COMPRESSION ) )
01377 {
01378 rc = true;
01379 }
01380 else
01381 {
01382 memset(&helper->strm,0,sizeof(helper->strm));
01383 helper->action = 0;
01384 }
01385 }
01386 else if ( 2 == helper->action )
01387 {
01388
01389 if ( Z_OK == inflateInit( &helper->strm ) )
01390 {
01391 rc = true;
01392 }
01393 else
01394 {
01395 memset(&helper->strm,0,sizeof(helper->strm));
01396 helper->action = 0;
01397 }
01398 }
01399 }
01400
01401 return rc;
01402 }
01403
01404 bool ON_CompressedBuffer::CompressionEnd( struct ON_CompressedBufferHelper* helper ) const
01405 {
01406 bool rc = false;
01407
01408 if ( helper )
01409 {
01410
01411 if ( 1 == helper->action )
01412 {
01413
01414 deflateEnd(&helper->strm);
01415 rc = true;
01416 }
01417 else if ( 2 == helper->action )
01418 {
01419
01420 inflateEnd(&helper->strm);
01421 rc = true;
01422 }
01423 memset(&helper->strm,0,sizeof(helper->strm));
01424 helper->action = 0;
01425 }
01426
01427 return rc;
01428 }
01429
01430