2008-06-23 Emmanuele Bassi <ebassi@openedhand.com>

Bug 981 - clutter_stage_read_pixels temprow fix (Haakon Sporsheim)

	* clutter/clutter-stage.c (clutter_stage_read_pixels): Allocate
	the temporary row data used to flip the buffer from glReadPixels()
	in order to fix compilation under MSVC. Also validate the input
	parameters to avoid random segfaults.
This commit is contained in:
Emmanuele Bassi 2008-06-23 10:06:02 +00:00
parent b241481586
commit 87d68544d0
2 changed files with 31 additions and 12 deletions

View File

@ -1,3 +1,12 @@
2008-06-23 Emmanuele Bassi <ebassi@openedhand.com>
Bug 981 - clutter_stage_read_pixels temprow fix (Haakon Sporsheim)
* clutter/clutter-stage.c (clutter_stage_read_pixels): Allocate
the temporary row data used to flip the buffer from glReadPixels()
in order to fix compilation under MSVC. Also validate the input
parameters to avoid random segfaults.
2008-06-23 Matthew Allum <mallum@openedhand.com> 2008-06-23 Matthew Allum <mallum@openedhand.com>
* clutter/clutter-actor.c: * clutter/clutter-actor.c:

View File

@ -1086,10 +1086,10 @@ clutter_stage_hide_cursor (ClutterStage *stage)
* *
* Makes a screenshot of the stage in RGBA 8bit data, returns a * Makes a screenshot of the stage in RGBA 8bit data, returns a
* linear buffer with @width * 4 as rowstride. * linear buffer with @width * 4 as rowstride.
* Gets a pixel based representation of the current rendered stage.
* *
* Return value: a pointer to newly allocated memory with the buffer * Return value: a pointer to newly allocated memory with the buffer
* that should be free with g_free, or NULL if the read back failed. * or %NULL if the read failed. Use g_free() on the returned data
* to release the resources it has allocated.
*/ */
guchar * guchar *
clutter_stage_read_pixels (ClutterStage *stage, clutter_stage_read_pixels (ClutterStage *stage,
@ -1099,6 +1099,7 @@ clutter_stage_read_pixels (ClutterStage *stage,
gint height) gint height)
{ {
guchar *pixels; guchar *pixels;
guchar *temprow;
GLint viewport[4]; GLint viewport[4];
gint rowstride; gint rowstride;
gint stage_x, stage_y, stage_width, stage_height; gint stage_x, stage_y, stage_width, stage_height;
@ -1117,11 +1118,19 @@ clutter_stage_read_pixels (ClutterStage *stage,
glGetIntegerv (GL_VIEWPORT, viewport); glGetIntegerv (GL_VIEWPORT, viewport);
stage_x = viewport[0]; stage_x = viewport[0];
stage_y = viewport[1]; stage_y = viewport[1];
stage_width = viewport[2] - x; stage_width = viewport[2];
stage_height = viewport[3] - y; stage_height = viewport[3];
if (width < 0 || width > stage_width)
width = stage_width;
if (height < 0 || height > stage_height)
height = stage_height;
rowstride = width * 4; rowstride = width * 4;
pixels = g_malloc (height * rowstride); pixels = g_malloc (height * rowstride);
temprow = g_malloc (rowstride);
/* check whether we need to read into a smaller temporary buffer */ /* check whether we need to read into a smaller temporary buffer */
glReadPixels (x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); glReadPixels (x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
@ -1129,7 +1138,6 @@ clutter_stage_read_pixels (ClutterStage *stage,
/* vertically flip the buffer in-place */ /* vertically flip the buffer in-place */
for (y = 0; y < height / 2; y++) for (y = 0; y < height / 2; y++)
{ {
guchar temprow[rowstride];
if (y != height - y - 1) /* skip center row */ if (y != height - y - 1) /* skip center row */
{ {
memcpy (temprow, memcpy (temprow,
@ -1142,6 +1150,8 @@ clutter_stage_read_pixels (ClutterStage *stage,
} }
} }
g_free (temprow);
return pixels; return pixels;
} }