From: José Fonseca Date: Sat, 9 Apr 2011 11:22:58 +0000 (+0100) Subject: Encode images in base64. X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;h=23a17d6b2666d5277ad3b4c04aa30fa3502fe2c4;p=apitrace Encode images in base64. --- diff --git a/glstate.py b/glstate.py index 96ba2b1..d46cf60 100644 --- a/glstate.py +++ b/glstate.py @@ -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;' diff --git a/json.hpp b/json.hpp index 7326891..9c491c5 100644 --- 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 - 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 + inline void writeNumberMember(const char *name, T n) { + beginMember(name); + writeNumber(n); + endMember(); + } }; #endif /* _JSON_HPP_ */