bool AtlasChunk::readFromStream(AtlasChunk *ac, Stream *s) { // First, read the size and allocate a buffer. // Let's do a sentinel check. U32 sent1; s->read(&sent1); AssertISV(sent1 == MakeFourCC('A', 'T', 'S', 'P'), "AtlasChunk::readFromStream - (sent1) invalid chunk master sentinel!"); s->read(&ac->mChunkSize); // And now validate the chunk-type-sentinel. U32 sent2; s->read(&sent2); AssertISV(sent2 == ac->getHeadSentinel(), "AtlasChunk::readFromStream - (sent2) invalid chunk head sentinel!"); // Get the chunk's data. If it's already in memory, just reuse it. // Otherwise read it from the stream. bool isMemStream = false; U8 *data; U32 dataSize = ac->mChunkSize; if( dynamic_cast< MemStream* >( s ) ) { MemStream* memStream = ( MemStream* ) s; U32 currentPos = memStream->getPosition(); isMemStream = true; data = &( ( U8* ) memStream->getBuffer() )[ currentPos ]; memStream->setPosition( currentPos + dataSize ); } else { data = new U8[ dataSize ]; // Read next chunksize bytes into the buffer for later processing. s->read( dataSize, data); } // Check end sentinel. U32 sent3; s->read(&sent3); AssertISV(sent3 == ac->getTailSentinel(), "AtlasChunk::readFromStream - (sent3) invalid chunk tail sentinel!"); // And tell the chunk to read from that buffer... MemStream dataStream( dataSize, data ); ac->read(&dataStream); // Clean up memory. if( !isMemStream ) delete[] data; // All done! return true; }
//-------------------------------------------------------------------------- static bool sWritePNG(GBitmap *bitmap, Stream &stream, U32 compressionLevel) { U32 waterMark = FrameAllocator::getWaterMark(); if ( compressionLevel < 10 ) { bool retVal = _writePNG(bitmap, stream, compressionLevel, 0, PNG_ALL_FILTERS); FrameAllocator::setWaterMark(waterMark); return retVal; } // check all our methods of compression to find the best one and use it U8* buffer = new U8[1 << 22]; // 4 Megs. Should be enough... MemStream* pMemStream = new MemStream(1 << 22, buffer, false, true); const U32 zStrategies[] = { Z_DEFAULT_STRATEGY, Z_FILTERED }; const U32 pngFilters[] = { PNG_FILTER_NONE, PNG_FILTER_SUB, PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, PNG_ALL_FILTERS }; U32 minSize = 0xFFFFFFFF; U32 bestStrategy = 0xFFFFFFFF; U32 bestFilter = 0xFFFFFFFF; U32 bestCLevel = 0xFFFFFFFF; for (U32 cl = 0; cl <=9; cl++) { for (U32 zs = 0; zs < 2; zs++) { for (U32 pf = 0; pf < 6; pf++) { pMemStream->setPosition(0); U32 waterMarkInner = FrameAllocator::getWaterMark(); if (_writePNG(bitmap, *pMemStream, cl, zStrategies[zs], pngFilters[pf]) == false) AssertFatal(false, "Handle this error!"); FrameAllocator::setWaterMark(waterMarkInner); if (pMemStream->getPosition() < minSize) { minSize = pMemStream->getPosition(); bestStrategy = zs; bestFilter = pf; bestCLevel = cl; } } } } AssertFatal(minSize != 0xFFFFFFFF, "Error, no best found?"); delete pMemStream; delete [] buffer; bool retVal = _writePNG(bitmap, stream, bestCLevel, zStrategies[bestStrategy], pngFilters[bestFilter]); FrameAllocator::setWaterMark(waterMark); return retVal; }