]> git.cworth.org Git - apitrace/commitdiff
Encode images in base64.
authorJosé Fonseca <jose.r.fonseca@gmail.com>
Sat, 9 Apr 2011 11:22:58 +0000 (12:22 +0100)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Sat, 9 Apr 2011 11:22:58 +0000 (12:22 +0100)
glstate.py
json.hpp

index 96ba2b1f76bbac300e7cef68055489b77f7be821..d46cf607f066beddc2e3c3e64e6ad790222901d2 100644 (file)
@@ -3037,8 +3037,6 @@ class StateDumper:
 static inline void
 writeTextureImage(JSONWriter &json, GLenum target, GLint level)
 {
-    json.beginMember("__image__");
-
     GLint width = 0, height = 0;
     glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width);
     glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height);
@@ -3046,22 +3044,51 @@ writeTextureImage(JSONWriter &json, GLenum target, GLint level)
     if (!width || !height) {
         json.writeNull();
     } else {
+        json.beginObject();
+
+        // Tell the GUI this is no ordinary object, but an image
+        json.writeStringMember("__class__", "image");
+
+        json.writeNumberMember("__width__", width);
+        json.writeNumberMember("__height__", height);
+        json.writeNumberMember("__depth__", 1);
+
+        // Hardcoded for now, but we could chose types more adequate to the
+        // texture internal format
+        json.writeStringMember("__type__", "float");
+        json.writeNumberMember("__channels__", 4);
+        
         float *pixels = new float[width*height*4];
+        
         glGetTexImage(target, level, GL_RGBA, GL_FLOAT, pixels);
-        json.beginArray();
-        for (GLint y = 0; y < height; ++y) {
+
+        if (0) {
+            json.writeStringMember("__encoding__", "array");
+            json.beginMember("__data__");
+
             json.beginArray();
-            for (GLint x = 0; x < width; ++x) {
+            for (GLint y = 0; y < height; ++y) {
                 json.beginArray();
-                for (GLint chan = 0; chan < 4; ++chan) {
-                    json.writeNumber(pixels[(y*width + x)*4 + chan]); 
+                for (GLint x = 0; x < width; ++x) {
+                    json.beginArray();
+                    for (GLint chan = 0; chan < 4; ++chan) {
+                        json.writeNumber(pixels[(y*width + x)*4 + chan]); 
+                    }
+                    json.endArray();
                 }
                 json.endArray();
             }
             json.endArray();
+            json.endMember(); // __data__
+        } else {
+            json.writeStringMember("__encoding__", "base64");
+            json.beginMember("__data__");
+            json.writeBase64(pixels, width * height * 4 * sizeof *pixels);
+            json.endMember(); // __data__
         }
-        json.endArray();
+
         delete [] pixels;
+        json.endObject();
     }
 }
 '''
@@ -3105,7 +3132,9 @@ writeTextureImage(JSONWriter &json, GLenum target, GLint level)
         print '        json.writeNumber(height);'
         print '        json.endMember();'
         print
+        print '        json.beginMember("image");'
         print '        writeTextureImage(json, target, level);'
+        print '        json.endMember();'
         print
         print '        json.endObject();'
         print '        ++level;'
index 7326891fd1f6939d4044b259f61e1ffe314d4687..9c491c552dcab93b94f09b6bef00a1636f0f7c8c 100644 (file)
--- a/json.hpp
+++ b/json.hpp
@@ -143,6 +143,66 @@ private:
         os << "\"";
     }
 
+    void encodeBase64String(const unsigned char *bytes, size_t size) {
+        const char *table64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+        unsigned char c0, c1, c2, c3;
+        char buf[4];
+        unsigned written;
+
+        os << "\"";
+
+        written = 0;
+        while (size >= 3) {
+            c0 = bytes[0] >> 2;
+            c1 = ((bytes[0] & 0x03) << 4) | ((bytes[1] & 0xf0) >> 4);
+            c2 = ((bytes[1] & 0x0f) << 2) | ((bytes[2] & 0xc0) >> 6);
+            c3 = bytes[2] & 0x3f;
+
+            buf[0] = table64[c0];
+            buf[1] = table64[c1];
+            buf[2] = table64[c2];
+            buf[3] = table64[c3];
+
+            os.write(buf, 4);
+
+            bytes += 3;
+            size -= 3;
+            ++written;
+
+            if (written >= 76/4) {
+                os << "\n";
+                written = 0;
+            }
+        }
+
+        if (size > 0) {
+            c0 = bytes[0] >> 2;
+            c1 = ((bytes[0] & 0x03) << 4);
+            
+            if (size > 1) {
+                c1 |= ((bytes[1] & 0xf0) >> 4);
+                c2 = ((bytes[1] & 0x0f) << 2);
+                if (size > 2) {
+                    c2 |= ((bytes[2] & 0xc0) >> 6);
+                    c3 = bytes[2] & 0x3f;
+                    buf[3] = table64[c3];
+                } else {
+                    buf[3] = '=';
+                }
+                buf[2] = table64[c2];
+            } else {
+                buf[3] = '=';
+                buf[2] = '=';
+            }
+            buf[1] = table64[c1];
+            buf[0] = table64[c0];
+
+            os.write(buf, 4);
+        }
+
+        os << "\"";
+    }
+
 public:
     JSONWriter(std::ostream &_os) : 
         os(_os), 
@@ -214,6 +274,13 @@ public:
         space = ' ';
     }
 
+    inline void writeBase64(const void *bytes, size_t size) {
+        separator();
+        encodeBase64String((const unsigned char *)bytes, size);
+        value = true;
+        space = ' ';
+    }
+
     inline void writeNull(void) {
         separator();
         os << "null";
@@ -229,12 +296,31 @@ public:
     }
 
     template<class T>
-    void writeNumber(T n) {
+    inline void writeNumber(T n) {
         separator();
         os << std::dec << n;
         value = true;
         space = ' ';
     }
+    
+    inline void writeStringMember(const char *name, const char *s) {
+        beginMember(name);
+        writeString(s);
+        endMember();
+    }
+
+    inline void writeBoolMember(const char *name, bool b) {
+        beginMember(name);
+        writeBool(b);
+        endMember();
+    }
+
+    template<class T>
+    inline void writeNumberMember(const char *name, T n) {
+        beginMember(name);
+        writeNumber(n);
+        endMember();
+    }
 };
 
 #endif /* _JSON_HPP_ */