]> git.cworth.org Git - apitrace/blobdiff - glstate.py
Prevent buffer overflow when dumping depth buffers with odd widths due to unpack...
[apitrace] / glstate.py
index cf136656c0f17a424b7643a7ac68fd0a61b1340f..6c6f25988e1246eb5f6e38532a50a8e5ac380cd2 100644 (file)
@@ -2958,6 +2958,7 @@ class StateDumper:
         print '#include "json.hpp"'
         print '#include "glimports.hpp"'
         print '#include "glproc.hpp"'
+        print '#include "glsize.hpp"'
         print '#include "glretrace.hpp"'
         print
 
@@ -3073,7 +3074,6 @@ writeTextureImage(JSONWriter &json, GLenum target, GLint level)
         
         glGetTexImage(target, level, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
 
-        json.writeStringMember("__encoding__", "base64");
         json.beginMember("__data__");
         json.writeBase64(pixels, depth * width * height * 4 * sizeof *pixels);
         json.endMember(); // __data__
@@ -3084,11 +3084,13 @@ writeTextureImage(JSONWriter &json, GLenum target, GLint level)
 }
 
 static inline void
-writeDrawBufferImage(JSONWriter &json)
+writeDrawBufferImage(JSONWriter &json, GLenum format)
 {
     GLint width  = glretrace::window_width;
     GLint height = glretrace::window_height;
 
+    GLint channels = __gl_format_channels(format);
+
     if (!width || !height) {
         json.writeNull();
     } else {
@@ -3105,21 +3107,26 @@ writeDrawBufferImage(JSONWriter &json)
         // texture internal format
         json.writeStringMember("__type__", "uint8");
         json.writeBoolMember("__normalized__", true);
-        json.writeNumberMember("__channels__", 4);
-        
-        GLubyte *pixels = new GLubyte[width*height*4];
+        json.writeNumberMember("__channels__", channels);
+
+        GLubyte *pixels = new GLubyte[width*height*channels];
         
         GLint drawbuffer = glretrace::double_buffer ? GL_BACK : GL_FRONT;
         GLint readbuffer = glretrace::double_buffer ? GL_BACK : GL_FRONT;
         glGetIntegerv(GL_DRAW_BUFFER, &drawbuffer);
         glGetIntegerv(GL_READ_BUFFER, &readbuffer);
         glReadBuffer(drawbuffer);
-        glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+        glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
+        glPixelStorei(GL_PACK_ALIGNMENT, 1);
+
+        glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, pixels);
+
+        glPopClientAttrib();
         glReadBuffer(readbuffer);
 
-        json.writeStringMember("__encoding__", "base64");
         json.beginMember("__data__");
-        json.writeBase64(pixels, width * height * 4 * sizeof *pixels);
+        json.writeBase64(pixels, width * height * channels * sizeof *pixels);
         json.endMember(); // __data__
 
         delete [] pixels;
@@ -3295,10 +3302,28 @@ writeDrawBufferImage(JSONWriter &json)
     def dump_framebuffer(self):
         print '    json.beginMember("framebuffer");'
         print '    json.beginObject();'
-        print '    json.beginMember("GL_DRAW_BUFFER");'
-        # TODO: Handle FBOs
-        print '    writeDrawBufferImage(json);'
+        # TODO: Handle real FBOs
+        print
+        print '    json.beginMember("GL_RGBA");'
+        print '    writeDrawBufferImage(json, GL_RGBA);'
         print '    json.endMember();'
+        print
+        print '    GLint depth_bits = 0;'
+        print '    glGetIntegerv(GL_DEPTH_BITS, &depth_bits);'
+        print '    if (depth_bits) {'
+        print '        json.beginMember("GL_DEPTH_COMPONENT");'
+        print '        writeDrawBufferImage(json, GL_DEPTH_COMPONENT);'
+        print '        json.endMember();'
+        print '    }'
+        print
+        print '    GLint stencil_bits = 0;'
+        print '    glGetIntegerv(GL_STENCIL_BITS, &stencil_bits);'
+        print '    if (stencil_bits) {'
+        print '        json.beginMember("GL_STENCIL_INDEX");'
+        print '        writeDrawBufferImage(json, GL_STENCIL_INDEX);'
+        print '        json.endMember();'
+        print '    }'
+        print
         print '    json.endObject();'
         print '    json.endMember(); // framebuffer'
         pass