Browse Source

Added image save as png to a Serializer stream. Due to stb_image_write limitations, the format is always png. Block-compressed (DXT etc.) image data is not supported. Closes #441.

Lasse Öörni 11 years ago
parent
commit
89074cf668
2 changed files with 33 additions and 0 deletions
  1. 31 0
      Source/Engine/Resource/Image.cpp
  2. 2 0
      Source/Engine/Resource/Image.h

+ 31 - 0
Source/Engine/Resource/Image.cpp

@@ -28,6 +28,7 @@
 #include "Log.h"
 #include "Log.h"
 #include "Profiler.h"
 #include "Profiler.h"
 
 
+#include <cstdlib>
 #include <cstring>
 #include <cstring>
 #include <stb_image.h>
 #include <stb_image.h>
 #include <stb_image_write.h>
 #include <stb_image_write.h>
@@ -36,6 +37,8 @@
 
 
 #include "DebugNew.h"
 #include "DebugNew.h"
 
 
+extern "C" unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len);
+
 #ifndef MAKEFOURCC
 #ifndef MAKEFOURCC
 #define MAKEFOURCC(ch0, ch1, ch2, ch3) ((unsigned)(ch0) | ((unsigned)(ch1) << 8) | ((unsigned)(ch2) << 16) | ((unsigned)(ch3) << 24))
 #define MAKEFOURCC(ch0, ch1, ch2, ch3) ((unsigned)(ch0) | ((unsigned)(ch1) << 8) | ((unsigned)(ch2) << 16) | ((unsigned)(ch3) << 24))
 #endif
 #endif
@@ -49,12 +52,14 @@
 namespace Urho3D
 namespace Urho3D
 {
 {
 
 
+/// DirectDraw color key definition.
 struct DDColorKey
 struct DDColorKey
 {
 {
     unsigned dwColorSpaceLowValue_;
     unsigned dwColorSpaceLowValue_;
     unsigned dwColorSpaceHighValue_;
     unsigned dwColorSpaceHighValue_;
 };
 };
 
 
+/// DirectDraw pixel format definition.
 struct DDPixelFormat
 struct DDPixelFormat
 {
 {
     unsigned dwSize_;
     unsigned dwSize_;
@@ -108,6 +113,7 @@ struct DDPixelFormat
     };
     };
 };
 };
 
 
+/// DirectDraw surface capabilities.
 struct DDSCaps2
 struct DDSCaps2
 {
 {
     unsigned dwCaps_;
     unsigned dwCaps_;
@@ -120,6 +126,7 @@ struct DDSCaps2
     };
     };
 };
 };
 
 
+/// DirectDraw surface description.
 struct DDSurfaceDesc2
 struct DDSurfaceDesc2
 {
 {
     unsigned dwSize_;
     unsigned dwSize_;
@@ -480,6 +487,30 @@ bool Image::BeginLoad(Deserializer& source)
     return true;
     return true;
 }
 }
 
 
+bool Image::Save(Serializer& dest) const
+{
+    PROFILE(SaveImage);
+
+    if (IsCompressed())
+    {
+        LOGERROR("Can not save compressed image " + GetName());
+        return false;
+    }
+
+    if (!data_)
+    {
+        LOGERROR("Can not save zero-sized image " + GetName());
+        return false;
+    }
+
+    int len;
+    unsigned char *png = stbi_write_png_to_mem(data_.Get(), 0, width_, height_, components_, &len);
+    bool success = dest.Write(png, len) == (unsigned)len;
+    free(png);
+    return success;
+}
+
+
 bool Image::SetSize(int width, int height, unsigned components)
 bool Image::SetSize(int width, int height, unsigned components)
 {
 {
     return SetSize(width, height, 1, components);
     return SetSize(width, height, 1, components);

+ 2 - 0
Source/Engine/Resource/Image.h

@@ -100,6 +100,8 @@ public:
 
 
     /// Load resource from stream. May be called from a worker thread. Return true if successful.
     /// Load resource from stream. May be called from a worker thread. Return true if successful.
     virtual bool BeginLoad(Deserializer& source);
     virtual bool BeginLoad(Deserializer& source);
+    /// Save the image to a stream. Regardless of original format, the image is saved as png. Compressed image data is not supported. Return true if successful.
+    virtual bool Save(Serializer& dest) const;
 
 
     /// Set 2D size and number of color components. Old image data will be destroyed and new data is undefined. Return true if successful.
     /// Set 2D size and number of color components. Old image data will be destroyed and new data is undefined. Return true if successful.
     bool SetSize(int width, int height, unsigned components);
     bool SetSize(int width, int height, unsigned components);