ソースを参照

Expanded Features

Added ability to set format dynamically on read from stream.
Added other formats to write to a stream.
marauder2k7 1 年間 前
コミット
43c2c918c7

+ 1 - 1
Engine/source/gfx/bitmap/gBitmap.cpp

@@ -1254,7 +1254,7 @@ bool GBitmap::writeBitmapStream(const String& bmType, Stream& ioStream, U32 comp
       return false;
    }
 
-   return regInfo->writeStreamFunc(ioStream, this, (compressionLevel == U32_MAX) ? regInfo->defaultCompression : compressionLevel);
+   return regInfo->writeStreamFunc(bmType, ioStream, this, (compressionLevel == U32_MAX) ? regInfo->defaultCompression : compressionLevel);
 }
 
 template<> void *Resource<GBitmap>::create(const Torque::Path &path)

+ 1 - 1
Engine/source/gfx/bitmap/gBitmap.h

@@ -75,7 +75,7 @@ public:
       typedef bool(*ReadStreamFunc)(Stream& stream, GBitmap* bitmap, U32 len);
       /// The write functions prototype.  Compression levels are image-specific - see their registration declaration for details.
       typedef bool(*WriteFunc)(const Torque::Path& path, GBitmap* bitmap, U32 compressionLevel);
-      typedef bool(*WriteStreamFunc)(Stream& stream, GBitmap* bitmap, U32 compressionLevel);
+      typedef bool(*WriteStreamFunc)(const String& bmType, Stream& stream, GBitmap* bitmap, U32 compressionLevel);
       
       /// Used to sort the registrations so that 
       /// lookups occur in a fixed order.

+ 66 - 21
Engine/source/gfx/bitmap/loaders/bitmapSTB.cpp

@@ -44,7 +44,15 @@ static bool sReadSTB(const Torque::Path& path, GBitmap* bitmap);
 static bool sReadStreamSTB(Stream& stream, GBitmap* bitmap, U32 len);
 
 static bool sWriteSTB(const Torque::Path& path, GBitmap* bitmap, U32 compressionLevel);
-static bool sWriteStreamSTB(Stream& stream, GBitmap* bitmap, U32 compressionLevel);
+static bool sWriteStreamSTB(const String& bmType, Stream& stream, GBitmap* bitmap, U32 compressionLevel);
+
+// stbi_write callback / rextimmy.
+static void stbiWriteFunc(void* context, void* data, int size)
+{
+   Stream* stream = static_cast<Stream*>(context);
+   stream->write(size);
+   stream->write(size, data);
+}
 
 static struct _privateRegisterSTB
 {
@@ -209,8 +217,21 @@ bool sReadStreamSTB(Stream& stream, GBitmap* bitmap, U32 len)
    stream.read(len, data);
 
    S32 width, height, comp = 0;
+   if (stbi_info_from_memory(data, len, &width, &height, &comp))
+   {
+      const char* stbErr = stbi_failure_reason();
+
+      if (!stbErr)
+         stbErr = "Unknown Error!";
+
+      Con::errorf("STB failed to get image info: %s", stbErr);
+      return false;
+   }
+
+   S32 reqCom = comp;
+
+   unsigned char* pixelData = stbi_load_from_memory((const U8*)data, (int)len, &width, &height, &comp, reqCom);
 
-   unsigned char* pixelData = stbi_load_from_memory((const U8*)data, (int)len, &width, &height, &comp, 1);
    if (!pixelData)
    {
       const char* stbErr = stbi_failure_reason();
@@ -218,12 +239,22 @@ bool sReadStreamSTB(Stream& stream, GBitmap* bitmap, U32 len)
       if (!stbErr)
          stbErr = "Unknown Error!";
 
-      Con::printf("sReadStreamSTB Error: %s", stbErr);
+      Con::errorf("sReadStreamSTB Error: %s", stbErr);
       return false;
    }
    bitmap->deleteImage();
 
-   bitmap->allocateBitmap(256, 256, false, GFXFormatA8);
+   //work out what format we need to use - todo floating point?
+   GFXFormat fmt = GFXFormat_FIRST;
+   switch (comp)
+   {
+   case 1: fmt = GFXFormatA8; break;
+   case 2: fmt = GFXFormatA8L8; break; //todo check this
+   case 3: fmt = GFXFormatR8G8B8; break;
+   case 4: fmt = GFXFormatR8G8B8A8; break;
+   }
+
+   bitmap->allocateBitmap(width, height, false, GFXFormatA8);
 
    U8* pBase = bitmap->getWritableBits(0);
    U32 rowBytes = bitmap->getByteSize();
@@ -311,27 +342,41 @@ bool sWriteSTB(const Torque::Path& path, GBitmap* bitmap, U32 compressionLevel)
    return false;
 }
 
-bool sWriteStreamSTB(Stream& stream, GBitmap* bitmap, U32 compressionLevel)
+bool sWriteStreamSTB(const String& bmType, Stream& stream, GBitmap* bitmap, U32 compressionLevel)
 {
-   S32 len;
-   const U8* pData = bitmap->getBits();
+   PROFILE_SCOPE(sWriteStreamSTB);
 
-   unsigned char* png = stbi_write_png_to_mem(pData, 0, bitmap->getWidth(), bitmap->getHeight(), 1, &len);
+   S32 width = bitmap->getWidth();
+   S32 height = bitmap->getHeight();
+   const U8* pPixelData = bitmap->getBits();
+   S32 channels = bitmap->getBytesPerPixel();
 
-   if (!png)
+   if (bmType == String("png"))
    {
-      const char* stbErr = stbi_failure_reason();
-
-      if (!stbErr)
-         stbErr = "Unknown Error!";
-
-      Con::printf("sReadStreamSTB Error: %s", stbErr);
-      return false;
+      stbi_write_png_compression_level = compressionLevel;
+      if (stbi_write_png_to_func(stbiWriteFunc, &stream, width, height, channels, pPixelData, width * channels))
+         return true;
+   }
+   else if (bmType == String("tga"))
+   {
+      if (stbi_write_tga_to_func(stbiWriteFunc, &stream, width, height, channels, pPixelData))
+         return true;
+   }
+   else if (bmType == String("bmp"))
+   {
+      if (stbi_write_bmp_to_func(stbiWriteFunc, &stream, width, height, channels, pPixelData))
+         return true;
+   }
+   else if (bmType == String("jpg") || bmType == String("jpeg"))
+   {
+      if (stbi_write_jpg_to_func(stbiWriteFunc, &stream, width, height, channels, pPixelData, compressionLevel))
+         return true;
+   }
+   else if (bmType == String("hdr"))
+   {
+      if (stbi_write_hdr_to_func(stbiWriteFunc, &stream, width, height, channels, (const F32*)pPixelData))
+         return true;
    }
 
-   stream.write(len);
-   stream.write(len, png);
-
-   dFree(png);
-   return true;
+   return false;
 }