예제 #1
0
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;
}
예제 #2
0
//--------------------------------------------------------------------------
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;
}