bitStream.cpp
Engine/source/core/stream/bitStream.cpp
Classes:
class
Public Variables
Detailed Description
Public Variables
U32 gBitCounts [4]
U8 gPacketBuffer [Net::MaxPacketDataSize]
BitStream gPacketStream (NULL, 0)
Public Functions
IsEqual(F32 a, F32 b)
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platform.h" 25#include "core/stream/bitStream.h" 26 27#include "core/strings/stringFunctions.h" 28#include "math/mathIO.h" 29#include "console/consoleObject.h" 30#include "platform/platformNet.h" 31#include "core/bitVector.h" 32 33 34static BitStream gPacketStream(NULL, 0); 35static U8 gPacketBuffer[Net::MaxPacketDataSize]; 36 37// bitstream utility functions 38 39void BitStream::clearStringBuffer() 40{ 41 static char stringBuf[256]; 42 stringBuf[0] = 0; 43// setStringBuffer( stringBuf ); 44} 45 46void BitStream::setStringBuffer(char buffer[256]) 47{ 48// stringBuffer = buffer; 49} 50 51BitStream *BitStream::getPacketStream(U32 writeSize) 52{ 53 if(!writeSize) 54 writeSize = Net::MaxPacketDataSize; 55 56 gPacketStream.setBuffer(gPacketBuffer, writeSize, Net::MaxPacketDataSize); 57 gPacketStream.setPosition(0); 58 59 return &gPacketStream; 60} 61 62void BitStream::sendPacketStream(const NetAddress *addr) 63{ 64 Net::sendto(addr, gPacketStream.getBuffer(), gPacketStream.getPosition()); 65} 66 67// CodeReview WTF is this additional IsEqual? - BJG, 3/29/07 68 69inline bool IsEqual(F32 a, F32 b) { return a == b; } 70 71ResizeBitStream::ResizeBitStream(U32 minSpace, U32 initialSize) : BitStream(NULL, 0, 0) 72{ 73 mMinSpace = minSpace; 74 if(!initialSize) 75 initialSize = minSpace * 2; 76 U8 *buf = (U8 *) dMalloc(initialSize); 77 setBuffer(buf, initialSize, initialSize); 78} 79 80ResizeBitStream::~ResizeBitStream() 81{ 82 dFree(dataPtr); 83} 84 85void ResizeBitStream::validate() 86{ 87 if(getPosition() + mMinSpace > bufSize) 88 { 89 bufSize = getPosition() + mMinSpace * 2; 90 dataPtr = (U8 *) dRealloc(dataPtr, bufSize); 91 92 maxReadBitNum = bufSize << 3; 93 maxWriteBitNum = bufSize << 3; 94 } 95} 96 97 98class HuffmanProcessor 99{ 100 static const U32 csm_charFreqs[256]; 101 bool m_tablesBuilt; 102 103 void buildTables(); 104 105 struct HuffNode { 106 U32 pop; 107 108 S16 index0; 109 S16 index1; 110 }; 111 struct HuffLeaf { 112 U32 pop; 113 114 U8 numBits; 115 U8 symbol; 116 U32 code; // no code should be longer than 32 bits. 117 }; 118 // We have to be a bit careful with these, mSince they are pointers... 119 struct HuffWrap { 120 HuffNode* pNode; 121 HuffLeaf* pLeaf; 122 123 public: 124 HuffWrap() : pNode(NULL), pLeaf(NULL) { } 125 126 void set(HuffLeaf* in_leaf) { pNode = NULL; pLeaf = in_leaf; } 127 void set(HuffNode* in_node) { pLeaf = NULL; pNode = in_node; } 128 129 U32 getPop() { if (pNode) return pNode->pop; else return pLeaf->pop; } 130 }; 131 132 Vector<HuffNode> m_huffNodes; 133 Vector<HuffLeaf> m_huffLeaves; 134 135 S16 determineIndex(HuffWrap&); 136 137 void generateCodes(BitStream&, S32, S32); 138 139 public: 140 HuffmanProcessor() : m_tablesBuilt(false) { } 141 142 static HuffmanProcessor g_huffProcessor; 143 144 bool readHuffBuffer(BitStream* pStream, char* out_pBuffer); 145 bool writeHuffBuffer(BitStream* pStream, const char* out_pBuffer, S32 maxLen); 146}; 147 148HuffmanProcessor HuffmanProcessor::g_huffProcessor; 149 150void BitStream::setBuffer(void *bufPtr, S32 size, S32 maxSize) 151{ 152 dataPtr = (U8 *) bufPtr; 153 bitNum = 0; 154 bufSize = size; 155 maxReadBitNum = size << 3; 156 if(maxSize < 0) 157 maxSize = size; 158 maxWriteBitNum = maxSize << 3; 159 error = false; 160 clearCompressionPoint(); 161} 162 163U32 BitStream::getPosition() const 164{ 165 return (bitNum + 7) >> 3; 166} 167 168 169bool BitStream::setPosition(const U32 pos) 170{ 171 bitNum = pos << 3; 172 return (true); 173} 174 175U32 BitStream::getStreamSize() 176{ 177 return bufSize; 178} 179 180U8 *BitStream::getBytePtr() 181{ 182 return dataPtr + getPosition(); 183} 184 185 186U32 BitStream::getReadByteSize() 187{ 188 return (maxReadBitNum >> 3) - getPosition(); 189} 190 191U32 BitStream::getWriteByteSize() 192{ 193 return (maxWriteBitNum >> 3) - getPosition(); 194} 195 196void BitStream::clear() 197{ 198 dMemset(dataPtr, 0, bufSize); 199} 200 201void BitStream::writeClassId(U32 classId, U32 classType, U32 classGroup) 202{ 203 AssertFatal(classType < NetClassTypesCount, "Out of range class type."); 204 AssertFatal(classGroup < NetClassGroupsCount, "Out of range class group."); 205 AssertFatal(classId < AbstractClassRep::NetClassCount[classGroup][classType], "Out of range class id."); 206 AssertFatal(AbstractClassRep::NetClassCount[classGroup][classType] < (1 << AbstractClassRep::NetClassBitSize[classGroup][classType]), 207 "NetClassBitSize too small!"); 208 209 writeInt(classId, AbstractClassRep::NetClassBitSize[classGroup][classType]); 210} 211 212S32 BitStream::readClassId(U32 classType, U32 classGroup) 213{ 214 AssertFatal(classType < NetClassTypesCount, "Out of range class type."); 215 AssertFatal(classGroup < NetClassGroupsCount, "Out of range class group."); 216 AssertFatal(AbstractClassRep::NetClassCount[classGroup][classType] < (1 << AbstractClassRep::NetClassBitSize[classGroup][classType]), 217 "NetClassBitSize too small!"); 218 219 S32 ret = readInt(AbstractClassRep::NetClassBitSize[classGroup][classType]); 220 221 AssertFatal(ret < AbstractClassRep::NetClassCount[classGroup][classType], "BitStream::readClassId - unexpected class ID!"); 222 if(ret >= AbstractClassRep::NetClassCount[classGroup][classType]) 223 return -1; 224 return ret; 225} 226 227void BitStream::writeBits(S32 bitCount, const void *bitPtr) 228{ 229 if(!bitCount) 230 return; 231 232 if(bitCount + bitNum > maxWriteBitNum) 233 { 234 error = true; 235 AssertFatal(false, "Out of range write"); 236 return; 237 } 238 239 // [tom, 8/17/2006] This is probably a lot lamer then it needs to be. However, 240 // at least it doesnt clobber data or overrun the buffer like the old code did. 241 const U8 *ptr = (U8 *)bitPtr; 242 243 for(S32 srcBitNum = 0;srcBitNum < bitCount;srcBitNum++) 244 { 245 if((*(ptr + (srcBitNum >> 3)) & (1 << (srcBitNum & 0x7))) != 0) 246 *(dataPtr + (bitNum >> 3)) |= (1 << (bitNum & 0x7)); 247 else 248 *(dataPtr + (bitNum >> 3)) &= ~(1 << (bitNum & 0x7)); 249 bitNum++; 250 } 251} 252 253void BitStream::setBit(S32 bitCount, bool set) 254{ 255 if(set) 256 *(dataPtr + (bitCount >> 3)) |= (1 << (bitCount & 0x7)); 257 else 258 *(dataPtr + (bitCount >> 3)) &= ~(1 << (bitCount & 0x7)); 259} 260 261bool BitStream::testBit(S32 bitCount) 262{ 263 return (*(dataPtr + (bitCount >> 3)) & (1 << (bitCount & 0x7))) != 0; 264} 265 266bool BitStream::writeFlag(bool val) 267{ 268 if(bitNum + 1 > maxWriteBitNum) 269 { 270 error = true; 271 AssertFatal(false, "Out of range write"); 272 return false; 273 } 274 if(val) 275 *(dataPtr + (bitNum >> 3)) |= (1 << (bitNum & 0x7)); 276 else 277 *(dataPtr + (bitNum >> 3)) &= ~(1 << (bitNum & 0x7)); 278 bitNum++; 279 return (val); 280} 281 282void BitStream::readBits(S32 bitCount, void *bitPtr) 283{ 284 if(!bitCount) 285 return; 286 if(bitCount + bitNum > maxReadBitNum) 287 { 288 error = true; 289 //AssertFatal(false, "Out of range read"); 290 AssertWarn(false, "Out of range read"); 291 return; 292 } 293 U8 *stPtr = dataPtr + (bitNum >> 3); 294 S32 byteCount = (bitCount + 7) >> 3; 295 296 U8 *ptr = (U8 *) bitPtr; 297 298 S32 downShift = bitNum & 0x7; 299 S32 upShift = 8 - downShift; 300 301 U8 curB = *stPtr; 302 const U8 *stEnd = dataPtr + bufSize; 303 while(byteCount--) 304 { 305 stPtr++; 306 U8 nextB = stPtr < stEnd ? *stPtr : 0; 307 *ptr++ = (curB >> downShift) | (nextB << upShift); 308 curB = nextB; 309 } 310 311 bitNum += bitCount; 312} 313 314bool BitStream::_read(U32 size, void *dataPtr) 315{ 316 readBits(size << 3, dataPtr); 317 return true; 318} 319 320bool BitStream::_write(U32 size, const void *dataPtr) 321{ 322 writeBits(size << 3, dataPtr); 323 return true; 324} 325 326S32 BitStream::readInt(S32 bitCount) 327{ 328 S32 ret = 0; 329 readBits(bitCount, &ret); 330 ret = convertLEndianToHost(ret); 331 if(bitCount == 32) 332 return ret; 333 else 334 ret &= (1 << bitCount) - 1; 335 return ret; 336} 337 338void BitStream::writeInt(S32 val, S32 bitCount) 339{ 340 AssertFatal((bitCount == 32) || ((val >> bitCount) == 0), avar("BitStream::writeInt: value out of range: %i/%i (%i bits)", val, 1 << bitCount, bitCount)); 341 342 val = convertHostToLEndian(val); 343 writeBits(bitCount, &val); 344} 345 346void BitStream::writeFloat(F32 f, S32 bitCount) 347{ 348 writeInt((S32)(f * ((1 << bitCount) - 1)), bitCount); 349} 350 351F32 BitStream::readFloat(S32 bitCount) 352{ 353 return readInt(bitCount) / F32((1 << bitCount) - 1); 354} 355 356void BitStream::writeSignedFloat(F32 f, S32 bitCount) 357{ 358 writeInt((S32)(((f + 1) * .5) * ((1 << bitCount) - 1)), bitCount); 359} 360 361F32 BitStream::readSignedFloat(S32 bitCount) 362{ 363 return readInt(bitCount) * 2 / F32((1 << bitCount) - 1) - 1.0f; 364} 365 366void BitStream::writeSignedInt(S32 value, S32 bitCount) 367{ 368 if(writeFlag(value < 0)) 369 writeInt(-value, bitCount - 1); 370 else 371 writeInt(value, bitCount - 1); 372} 373 374S32 BitStream::readSignedInt(S32 bitCount) 375{ 376 if(readFlag()) 377 return -readInt(bitCount - 1); 378 else 379 return readInt(bitCount - 1); 380} 381 382void BitStream::writeNormalVector(const Point3F& vec, S32 bitCount) 383{ 384 F32 phi = mAtan2(vec.x, vec.y) / M_PI; 385 F32 theta = mAtan2(vec.z, mSqrt(vec.x*vec.x + vec.y*vec.y)) / (M_PI/2.0); 386 387 writeSignedFloat(phi, bitCount+1); 388 writeSignedFloat(theta, bitCount); 389} 390 391void BitStream::readNormalVector(Point3F *vec, S32 bitCount) 392{ 393 F32 phi = readSignedFloat(bitCount+1) * M_PI; 394 F32 theta = readSignedFloat(bitCount) * (M_PI/2.0); 395 396 vec->x = mSin(phi)*mCos(theta); 397 vec->y = mCos(phi)*mCos(theta); 398 vec->z = mSin(theta); 399} 400 401Point3F BitStream::dumbDownNormal(const Point3F& vec, S32 bitCount) 402{ 403 U8 buffer[128]; 404 BitStream temp(buffer, 128); 405 406 temp.writeNormalVector(vec, bitCount); 407 temp.setCurPos(0); 408 409 Point3F ret; 410 temp.readNormalVector(&ret, bitCount); 411 return ret; 412} 413 414void BitStream::writeVector( Point3F vec, F32 maxMag, S32 magBits, S32 normalBits ) 415{ 416 F32 mag = vec.len(); 417 418 // If its zero length then we're done. 419 if ( !writeFlag( mag > 0.0f ) ) 420 return; 421 422 // Write the magnitude compressed unless its greater than the maximum. 423 if ( writeFlag( mag < maxMag ) ) 424 writeFloat( mag / maxMag, magBits ); 425 else 426 write( mag ); 427 428 // Finally write the normal part. 429 vec *= 1.0f / mag; 430 writeNormalVector( vec, normalBits ); 431} 432 433void BitStream::readVector( Point3F *outVec, F32 maxMag, S32 magBits, S32 normalBits ) 434{ 435 // Nothing more to do if we got a zero length vector. 436 if ( !readFlag() ) 437 { 438 outVec->set(0,0,0); 439 return; 440 } 441 442 // Read the compressed or uncompressed magnitude. 443 F32 mag; 444 if ( readFlag() ) 445 mag = readFloat( magBits ) * maxMag; 446 else 447 read( &mag ); 448 449 // Finally read the normal and reconstruct the vector. 450 readNormalVector( outVec, normalBits ); 451 *outVec *= mag; 452} 453 454void BitStream::writeAffineTransform(const MatrixF& matrix) 455{ 456// AssertFatal(matrix.isAffine() == true, 457// "BitStream::writeAffineTransform: Error, must write only affine transforms!"); 458 459 Point3F pos; 460 matrix.getColumn(3, &pos); 461 mathWrite(*this, pos); 462 463 QuatF q(matrix); 464 q.normalize(); 465 write(q.x); 466 write(q.y); 467 write(q.z); 468 writeFlag(q.w < 0.0); 469} 470 471void BitStream::readAffineTransform(MatrixF* matrix) 472{ 473 Point3F pos; 474 QuatF q; 475 476 mathRead(*this, &pos); 477 read(&q.x); 478 read(&q.y); 479 read(&q.z); 480 q.w = mSqrt(1.0 - getMin(F32(((q.x * q.x) + (q.y * q.y) + (q.z * q.z))), 1.f)); 481 if (readFlag()) 482 q.w = -q.w; 483 484 q.setMatrix(matrix); 485 matrix->setColumn(3, pos); 486// AssertFatal(matrix->isAffine() == true, 487// "BitStream::readAffineTransform: Error, transform should be affine after this function!"); 488} 489 490void BitStream::writeQuat( const QuatF& quat, U32 bitCount ) 491{ 492 writeSignedFloat( quat.x, bitCount ); 493 writeSignedFloat( quat.y, bitCount ); 494 writeSignedFloat( quat.z, bitCount ); 495 writeFlag( quat.w < 0.0f ); 496} 497 498void BitStream::readQuat( QuatF *outQuat, U32 bitCount ) 499{ 500 outQuat->x = readSignedFloat( bitCount ); 501 outQuat->y = readSignedFloat( bitCount ); 502 outQuat->z = readSignedFloat( bitCount ); 503 504 outQuat->w = mSqrt( 1.0 - getMin( mSquared( outQuat->x ) + 505 mSquared( outQuat->y ) + 506 mSquared( outQuat->z ), 507 1.0f ) ); 508 if ( readFlag() ) 509 outQuat->w = -outQuat->w; 510} 511 512void BitStream::writeBits( const BitVector &bitvec ) 513{ 514 U32 size = bitvec.getSize(); 515 if ( writeFlag( size <= 127 ) ) 516 writeInt( size, 7 ); 517 else 518 write( size ); 519 520 writeBits( bitvec.getSize(), bitvec.getBits() ); 521} 522 523void BitStream::readBits( BitVector *bitvec ) 524{ 525 U32 size; 526 if ( readFlag() ) // size <= 127 527 size = readInt( 7 ); 528 else 529 read( &size ); 530 531 bitvec->setSize( size ); 532 readBits( size, bitvec->getBits() ); 533} 534 535//---------------------------------------------------------------------------- 536 537void BitStream::clearCompressionPoint() 538{ 539 mCompressPoint.set(0,0,0); 540} 541 542void BitStream::setCompressionPoint(const Point3F& p) 543{ 544 mCompressPoint = p; 545} 546 547static U32 gBitCounts[4] = { 548 16, 18, 20, 32 549}; 550 551void BitStream::writeCompressedPoint(const Point3F& p,F32 scale) 552{ 553 // Same # of bits for all axis 554 Point3F vec; 555 F32 invScale = 1 / scale; 556 U32 type; 557 vec = p - mCompressPoint; 558 F32 dist = vec.len() * invScale; 559 if(dist < (1 << 15)) 560 type = 0; 561 else if(dist < (1 << 17)) 562 type = 1; 563 else if(dist < (1 << 19)) 564 type = 2; 565 else 566 type = 3; 567 568 writeInt(type, 2); 569 570 if (type != 3) 571 { 572 type = gBitCounts[type]; 573 writeSignedInt(S32(vec.x * invScale + 0.5f),type); 574 writeSignedInt(S32(vec.y * invScale + 0.5f),type); 575 writeSignedInt(S32(vec.z * invScale + 0.5f),type); 576 } 577 else 578 { 579 write(p.x); 580 write(p.y); 581 write(p.z); 582 } 583} 584 585void BitStream::readCompressedPoint(Point3F* p,F32 scale) 586{ 587 // Same # of bits for all axis 588 U32 type = readInt(2); 589 590 if(type == 3) 591 { 592 read(&p->x); 593 read(&p->y); 594 read(&p->z); 595 } 596 else 597 { 598 type = gBitCounts[type]; 599 p->x = (F32)readSignedInt(type); 600 p->y = (F32)readSignedInt(type); 601 p->z = (F32)readSignedInt(type); 602 603 p->x = mCompressPoint.x + p->x * scale; 604 p->y = mCompressPoint.y + p->y * scale; 605 p->z = mCompressPoint.z + p->z * scale; 606 } 607} 608 609//------------------------------------------------------------------------------ 610 611InfiniteBitStream::InfiniteBitStream() 612{ 613 // 614} 615 616InfiniteBitStream::~InfiniteBitStream() 617{ 618 // 619} 620 621void InfiniteBitStream::reset() 622{ 623 // Rewing back to beginning 624 setPosition(0); 625} 626 627void InfiniteBitStream::validate(U32 upcomingBytes) 628{ 629 if(getPosition() + upcomingBytes + mMinSpace > bufSize) 630 { 631 bufSize = getPosition() + upcomingBytes + mMinSpace; 632 dataPtr = (U8 *) dRealloc(dataPtr, bufSize); 633 634 maxReadBitNum = bufSize << 3; 635 maxWriteBitNum = bufSize << 3; 636 } 637} 638 639void InfiniteBitStream::compact() 640{ 641 // Prepare to copy... 642 U32 oldSize = bufSize; 643 U8 *tmp = (U8*)dMalloc(bufSize); 644 645 // Copy things... 646 bufSize = getPosition() + mMinSpace * 2; 647 dMemcpy(tmp, dataPtr, oldSize); 648 649 // And clean up. 650 dFree(dataPtr); 651 dataPtr = tmp; 652 653 maxReadBitNum = bufSize << 3; 654 maxWriteBitNum = bufSize << 3; 655} 656 657void InfiniteBitStream::writeToStream(Stream &s) 658{ 659 s.write(getPosition(), dataPtr); 660} 661 662//------------------------------------------------------------------------------ 663 664void BitStream::readString(char buf[256]) 665{ 666 if(stringBuffer) 667 { 668 if(readFlag()) 669 { 670 S32 offset = readInt(8); 671 HuffmanProcessor::g_huffProcessor.readHuffBuffer(this, stringBuffer + offset); 672 dStrcpy(buf, stringBuffer); 673 return; 674 } 675 } 676 HuffmanProcessor::g_huffProcessor.readHuffBuffer(this, buf); 677 if(stringBuffer) 678 dStrcpy(stringBuffer, buf); 679} 680 681void BitStream::writeString(const char *string, S32 maxLen) 682{ 683 if(!string) 684 string = ""; 685 if(stringBuffer) 686 { 687 S32 j; 688 for(j = 0; j < maxLen && stringBuffer[j] == string[j] && string[j];j++) 689 ; 690 dStrncpy(stringBuffer, string, maxLen); 691 stringBuffer[maxLen] = 0; 692 693 if(writeFlag(j > 2)) 694 { 695 writeInt(j, 8); 696 HuffmanProcessor::g_huffProcessor.writeHuffBuffer(this, string + j, maxLen - j); 697 return; 698 } 699 } 700 HuffmanProcessor::g_huffProcessor.writeHuffBuffer(this, string, maxLen); 701} 702 703void HuffmanProcessor::buildTables() 704{ 705 AssertFatal(m_tablesBuilt == false, "Cannot build tables twice!"); 706 m_tablesBuilt = true; 707 708 S32 i; 709 710 // First, construct the array of wraps... 711 // 712 m_huffLeaves.setSize(256); 713 m_huffNodes.reserve(256); 714 m_huffNodes.increment(); 715 for (i = 0; i < 256; i++) { 716 HuffLeaf& rLeaf = m_huffLeaves[i]; 717 718 rLeaf.pop = csm_charFreqs[i] + 1; 719 rLeaf.symbol = U8(i); 720 721 dMemset(&rLeaf.code, 0, sizeof(rLeaf.code)); 722 rLeaf.numBits = 0; 723 } 724 725 S32 currWraps = 256; 726 HuffWrap* pWrap = new HuffWrap[256]; 727 for (i = 0; i < 256; i++) { 728 pWrap[i].set(&m_huffLeaves[i]); 729 } 730 731 while (currWraps != 1) { 732 U32 min1 = 0xfffffffe, min2 = 0xffffffff; 733 S32 index1 = -1, index2 = -1; 734 735 for (i = 0; i < currWraps; i++) { 736 if (pWrap[i].getPop() < min1) { 737 min2 = min1; 738 index2 = index1; 739 740 min1 = pWrap[i].getPop(); 741 index1 = i; 742 } else if (pWrap[i].getPop() < min2) { 743 min2 = pWrap[i].getPop(); 744 index2 = i; 745 } 746 } 747 AssertFatal(index1 != -1 && index2 != -1 && index1 != index2, "hrph"); 748 749 // Create a node for this... 750 m_huffNodes.increment(); 751 HuffNode& rNode = m_huffNodes.last(); 752 rNode.pop = pWrap[index1].getPop() + pWrap[index2].getPop(); 753 rNode.index0 = determineIndex(pWrap[index1]); 754 rNode.index1 = determineIndex(pWrap[index2]); 755 756 S32 mergeIndex = index1 > index2 ? index2 : index1; 757 S32 nukeIndex = index1 > index2 ? index1 : index2; 758 pWrap[mergeIndex].set(&rNode); 759 760 if (index2 != (currWraps - 1)) { 761 pWrap[nukeIndex] = pWrap[currWraps - 1]; 762 } 763 currWraps--; 764 } 765 AssertFatal(currWraps == 1, "wrong wraps?"); 766 AssertFatal(pWrap[0].pNode != NULL && pWrap[0].pLeaf == NULL, "Wrong wrap type!"); 767 768 // Ok, now we have one wrap, which is a node. we need to make sure that this 769 // is the first node in the node list. 770 m_huffNodes[0] = *(pWrap[0].pNode); 771 delete [] pWrap; 772 773 U32 code = 0; 774 BitStream bs(&code, 4); 775 776 generateCodes(bs, 0, 0); 777} 778 779void HuffmanProcessor::generateCodes(BitStream& rBS, S32 index, S32 depth) 780{ 781 if (index < 0) { 782 // leaf node, copy the code in, and back out... 783 HuffLeaf& rLeaf = m_huffLeaves[-(index + 1)]; 784 785 dMemcpy(&rLeaf.code, rBS.dataPtr, sizeof(rLeaf.code)); 786 rLeaf.numBits = depth; 787 } else { 788 HuffNode& rNode = m_huffNodes[index]; 789 790 S32 pos = rBS.getCurPos(); 791 792 rBS.writeFlag(false); 793 generateCodes(rBS, rNode.index0, depth + 1); 794 795 rBS.setCurPos(pos); 796 rBS.writeFlag(true); 797 generateCodes(rBS, rNode.index1, depth + 1); 798 799 rBS.setCurPos(pos); 800 } 801} 802 803S16 HuffmanProcessor::determineIndex(HuffWrap& rWrap) 804{ 805 if (rWrap.pLeaf != NULL) { 806 AssertFatal(rWrap.pNode == NULL, "Got a non-NULL pNode in a HuffWrap with a non-NULL leaf."); 807 808 return -((rWrap.pLeaf - m_huffLeaves.address()) + 1); 809 } else { 810 AssertFatal(rWrap.pNode != NULL, "Got a NULL pNode in a HuffWrap with a NULL leaf."); 811 812 return rWrap.pNode - m_huffNodes.address(); 813 } 814} 815 816bool HuffmanProcessor::readHuffBuffer(BitStream* pStream, char* out_pBuffer) 817{ 818 if (m_tablesBuilt == false) 819 buildTables(); 820 821 if (pStream->readFlag()) { 822 S32 len = pStream->readInt(8); 823 for (S32 i = 0; i < len; i++) { 824 S32 index = 0; 825 while (true) { 826 if (index >= 0) { 827 if (pStream->readFlag() == true) { 828 index = m_huffNodes[index].index1; 829 } else { 830 index = m_huffNodes[index].index0; 831 } 832 } else { 833 out_pBuffer[i] = m_huffLeaves[-(index+1)].symbol; 834 break; 835 } 836 } 837 } 838 out_pBuffer[len] = '\0'; 839 return true; 840 } else { 841 // Uncompressed string... 842 U32 len = pStream->readInt(8); 843 pStream->read(len, out_pBuffer); 844 out_pBuffer[len] = '\0'; 845 return true; 846 } 847} 848 849bool HuffmanProcessor::writeHuffBuffer(BitStream* pStream, const char* out_pBuffer, S32 maxLen) 850{ 851 if (out_pBuffer == NULL) { 852 pStream->writeFlag(false); 853 pStream->writeInt(0, 8); 854 return true; 855 } 856 857 if (m_tablesBuilt == false) 858 buildTables(); 859 860 S32 len = out_pBuffer ? dStrlen(out_pBuffer) : 0; 861 AssertWarn(len <= 255, "String TOO long for writeString"); 862 AssertWarn(len <= 255, out_pBuffer); 863 if (len > maxLen) 864 len = maxLen; 865 866 S32 numBits = 0; 867 S32 i; 868 for (i = 0; i < len; i++) 869 numBits += m_huffLeaves[(unsigned char)out_pBuffer[i]].numBits; 870 871 if (numBits >= (len * 8)) { 872 pStream->writeFlag(false); 873 pStream->writeInt(len, 8); 874 pStream->write(len, out_pBuffer); 875 } else { 876 pStream->writeFlag(true); 877 pStream->writeInt(len, 8); 878 for (i = 0; i < len; i++) { 879 HuffLeaf& rLeaf = m_huffLeaves[((unsigned char)out_pBuffer[i])]; 880 pStream->writeBits(rLeaf.numBits, &rLeaf.code); 881 } 882 } 883 884 return true; 885} 886 887const U32 HuffmanProcessor::csm_charFreqs[256] = { 8880 , 8890 , 8900 , 8910 , 8920 , 8930 , 8940 , 8950 , 8960 , 897329 , 89821 , 8990 , 9000 , 9010 , 9020 , 9030 , 9040 , 9050 , 9060 , 9070 , 9080 , 9090 , 9100 , 9110 , 9120 , 9130 , 9140 , 9150 , 9160 , 9170 , 9180 , 9190 , 9202809 , 92168 , 9220 , 92327 , 9240 , 92558 , 9263 , 92762 , 9284 , 9297 , 9300 , 9310 , 93215 , 93365 , 934554 , 9353 , 936394 , 937404 , 938189 , 939117 , 94030 , 94151 , 94227 , 94315 , 94434 , 94532 , 94680 , 9471 , 948142 , 9493 , 950142 , 95139 , 9520 , 953144 , 954125 , 95544 , 956122 , 957275 , 95870 , 959135 , 96061 , 961127 , 9628 , 96312 , 964113 , 965246 , 966122 , 96736 , 968185 , 9691 , 970149 , 971309 , 972335 , 97312 , 97411 , 97514 , 97654 , 977151 , 9780 , 9790 , 9802 , 9810 , 9820 , 983211 , 9840 , 9852090 , 986344 , 987736 , 988993 , 9892872 , 990701 , 991605 , 992646 , 9931552 , 994328 , 995305 , 9961240 , 997735 , 9981533 , 9991713 , 1000562 , 10013 , 10021775 , 10031149 , 10041469 , 1005979 , 1006407 , 1007553 , 100859 , 1009279 , 101031 , 10110 , 10120 , 10130 , 101468 , 10150 , 10160 , 10170 , 10180 , 10190 , 10200 , 10210 , 10220 , 10230 , 10240 , 10250 , 10260 , 10270 , 10280 , 10290 , 10300 , 10310 , 10320 , 10330 , 10340 , 10350 , 10360 , 10370 , 10380 , 10390 , 10400 , 10410 , 10420 , 10430 , 10440 , 10450 , 10460 , 10470 , 10480 , 10490 , 10500 , 10510 , 10520 , 10530 , 10540 , 10550 , 10560 , 10570 , 10580 , 10590 , 10600 , 10610 , 10620 , 10630 , 10640 , 10650 , 10660 , 10670 , 10680 , 10690 , 10700 , 10710 , 10720 , 10730 , 10740 , 10750 , 10760 , 10770 , 10780 , 10790 , 10800 , 10810 , 10820 , 10830 , 10840 , 10850 , 10860 , 10870 , 10880 , 10890 , 10900 , 10910 , 10920 , 10930 , 10940 , 10950 , 10960 , 10970 , 10980 , 10990 , 11000 , 11010 , 11020 , 11030 , 11040 , 11050 , 11060 , 11070 , 11080 , 11090 , 11100 , 11110 , 11120 , 11130 , 11140 , 11150 , 11160 , 11170 , 11180 , 11190 , 11200 , 11210 , 11220 , 11230 , 11240 , 11250 , 11260 , 11270 , 11280 , 11290 , 11300 , 11310 , 11320 , 11330 , 11340 , 11350 , 11360 , 11370 , 11380 , 11390 , 11400 , 11410 , 11420 , 11430 1144}; 1145 1146
