size_t BitmapEncoding::Bitmap::compress(void* dst, const ConstChunk& chunk, size_t chunkSize) { char const* dataSrc = (char const*)chunk.getData(); TypeId type = chunk.getAttributeDesc().getType(); _elementSize = TypeLibrary::getType(type).byteSize(); /* No more immutable arrays, to keep consistent with old code, always treat data as string */ _bitmapElements = chunkSize; _elementSize = 1; if(!_bitmapElements) { return chunkSize; } char *readPos = const_cast<char *>(dataSrc); ByteOutputItr out((uint8_t *) dst, chunkSize-1); uint32_t i; uint32_t bucketSize = (_bitmapElements + 7) >> 3; uint32_t bucketCount = 0; std::string key; clearBitmapCache(); // make the key of our hash a string so that // we can compare variable-length element sizes size_t bitmapEntryLength = bucketSize + _elementSize; assert(bitmapEntryLength); uint32_t maxBuckets = floor(chunkSize / bitmapEntryLength); if(maxBuckets * bitmapEntryLength == chunkSize) { // we want to beat the uncompressed case --maxBuckets; } for(i = 0; i < _bitmapElements; ++i) { key.clear(); for(uint32_t j = 0; j < _elementSize; ++j) { key.push_back(*readPos); ++readPos; } uint8_t *bucket = NULL; // check to see if a bucket exists, if so grab and pass on std::map<std::string, uint8_t*>::iterator iter = _bitmaps.find(key); if(iter == _bitmaps.end() ) { ++bucketCount; if(bucketCount > maxBuckets) { return chunkSize; } // create a new one bucket = new uint8_t[bucketSize]; _bitmaps[key] = bucket; for(uint32_t k = 0; k < bucketSize; ++k) { *(bucket+k) = 0;} } else { bucket = iter->second; } assert(bucket!=NULL); setBit(bucket, i); } // drop all of bitmaps to dst fillOutput(&out); size_t compressedSize = out.close(); return compressedSize; }
TextRendererPrivate::~TextRendererPrivate() { clearUsedTextures(); clearBitmapCache(); }