Fix Crash When Taking Odd-Sized Screenshots
This commit is contained in:
parent
866ebfe159
commit
68a252c3df
@ -1,5 +1,8 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
**2.2.3**
|
||||||
|
* Fix Crash When Taking Odd-Sized Screenshots
|
||||||
|
|
||||||
**2.2.2**
|
**2.2.2**
|
||||||
* Add More Missing Sound Events
|
* Add More Missing Sound Events
|
||||||
* Make Missing Sound Event Cause Warning Rather Than Crash
|
* Make Missing Sound Event Cause Warning Rather Than Crash
|
||||||
|
@ -71,6 +71,16 @@ void media_take_screenshot(char *home) {
|
|||||||
|
|
||||||
// Get Line Size
|
// Get Line Size
|
||||||
int line_size = width * 3;
|
int line_size = width * 3;
|
||||||
|
{
|
||||||
|
// Handle Alignment
|
||||||
|
int alignment;
|
||||||
|
glGetIntegerv(GL_PACK_ALIGNMENT, &alignment);
|
||||||
|
// Round
|
||||||
|
int diff = line_size % alignment;
|
||||||
|
if (diff > 0) {
|
||||||
|
line_size = line_size + (alignment - diff);
|
||||||
|
}
|
||||||
|
}
|
||||||
int size = height * line_size;
|
int size = height * line_size;
|
||||||
|
|
||||||
// Read Pixels
|
// Read Pixels
|
||||||
@ -80,13 +90,16 @@ void media_take_screenshot(char *home) {
|
|||||||
// Handle Little Endian Systems
|
// Handle Little Endian Systems
|
||||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
// Swap Red And Blue
|
// Swap Red And Blue
|
||||||
for (int i = 0; i < (size / 3); i++) {
|
for (int j = 0; j < width; j++) {
|
||||||
int pixel = i * 3;
|
for (int k = 0; k < height; k++) {
|
||||||
|
int pixel = (k * line_size) + (j * 3);
|
||||||
|
// Swap
|
||||||
int red = pixels[pixel];
|
int red = pixels[pixel];
|
||||||
int blue = pixels[pixel + 2];
|
int blue = pixels[pixel + 2];
|
||||||
pixels[pixel] = blue;
|
pixels[pixel] = blue;
|
||||||
pixels[pixel + 2] = red;
|
pixels[pixel + 2] = red;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Save Image
|
// Save Image
|
||||||
|
@ -14,6 +14,8 @@ extern "C" {
|
|||||||
#define GL_PROJECTION_MATRIX 0xba7
|
#define GL_PROJECTION_MATRIX 0xba7
|
||||||
#define GL_VIEWPORT 0xba2
|
#define GL_VIEWPORT 0xba2
|
||||||
#define GL_DEPTH_TEST 0xb71
|
#define GL_DEPTH_TEST 0xb71
|
||||||
|
#define GL_PACK_ALIGNMENT 0xd05
|
||||||
|
#define GL_UNPACK_ALIGNMENT 0xcf5
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -334,7 +334,6 @@ static int get_texture_size(GLsizei width, GLsizei height, GLenum format, GLenum
|
|||||||
if (type == GL_UNSIGNED_BYTE) {
|
if (type == GL_UNSIGNED_BYTE) {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case GL_RGB: {
|
case GL_RGB: {
|
||||||
PROXY_ERR("%s", "WIP");
|
|
||||||
multiplier = 3;
|
multiplier = 3;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -349,11 +348,29 @@ static int get_texture_size(GLsizei width, GLsizei height, GLenum format, GLenum
|
|||||||
} else {
|
} else {
|
||||||
multiplier = sizeof (unsigned short);
|
multiplier = sizeof (unsigned short);
|
||||||
}
|
}
|
||||||
return width * height * multiplier; // This Should Have The Same Behavior On 32-Bit And 64-Bit Systems
|
int line_size = width * multiplier;
|
||||||
|
{
|
||||||
|
// Handle Alignment
|
||||||
|
int alignment;
|
||||||
|
glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
|
||||||
|
// Round
|
||||||
|
int diff = line_size % alignment;
|
||||||
|
if (diff > 0) {
|
||||||
|
line_size = line_size + (alignment - diff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return line_size * height; // This Should Have The Same Behavior On 32-Bit And 64-Bit Systems
|
||||||
}
|
}
|
||||||
|
|
||||||
CALL(25, glTexImage2D, void, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels)) {
|
CALL(25, glTexImage2D, void, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels)) {
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||||
|
// Get Texture Size
|
||||||
|
unsigned char is_null = pixels == NULL;
|
||||||
|
int size;
|
||||||
|
if (!is_null) {
|
||||||
|
size = get_texture_size(width, height, format, type);
|
||||||
|
}
|
||||||
|
|
||||||
// Lock Proxy
|
// Lock Proxy
|
||||||
start_proxy_call();
|
start_proxy_call();
|
||||||
|
|
||||||
@ -366,10 +383,8 @@ CALL(25, glTexImage2D, void, (GLenum target, GLint level, GLint internalformat,
|
|||||||
write_int((uint32_t) border);
|
write_int((uint32_t) border);
|
||||||
write_int((uint32_t) format);
|
write_int((uint32_t) format);
|
||||||
write_int((uint32_t) type);
|
write_int((uint32_t) type);
|
||||||
unsigned char is_null = pixels == NULL;
|
|
||||||
write_byte(is_null);
|
write_byte(is_null);
|
||||||
if (!is_null) {
|
if (!is_null) {
|
||||||
int size = get_texture_size(width, height, format, type);
|
|
||||||
safe_write((void *) pixels, (size_t) size);
|
safe_write((void *) pixels, (size_t) size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -714,6 +729,13 @@ CALL(43, glColorMask, void, (GLboolean red, GLboolean green, GLboolean blue, GLb
|
|||||||
|
|
||||||
CALL(44, glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)) {
|
CALL(44, glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)) {
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||||
|
// Get Texture Size
|
||||||
|
unsigned char is_null = pixels == NULL;
|
||||||
|
int size;
|
||||||
|
if (!is_null) {
|
||||||
|
size = get_texture_size(width, height, format, type);
|
||||||
|
}
|
||||||
|
|
||||||
// Lock Proxy
|
// Lock Proxy
|
||||||
start_proxy_call();
|
start_proxy_call();
|
||||||
|
|
||||||
@ -726,10 +748,8 @@ CALL(44, glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLin
|
|||||||
write_int((uint32_t) height);
|
write_int((uint32_t) height);
|
||||||
write_int((uint32_t) format);
|
write_int((uint32_t) format);
|
||||||
write_int((uint32_t) type);
|
write_int((uint32_t) type);
|
||||||
unsigned char is_null = pixels == NULL;
|
|
||||||
write_byte(is_null);
|
write_byte(is_null);
|
||||||
if (!is_null) {
|
if (!is_null) {
|
||||||
int size = get_texture_size(width, height, format, type);
|
|
||||||
safe_write((void *) pixels, (size_t) size);
|
safe_write((void *) pixels, (size_t) size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -852,7 +872,7 @@ CALL(48, glGetFloatv, void, (GLenum pname, GLfloat *params)) {
|
|||||||
|
|
||||||
// Get Return Value
|
// Get Return Value
|
||||||
int size = get_glGetFloatv_params_size(pname);
|
int size = get_glGetFloatv_params_size(pname);
|
||||||
safe_read((void *) params, sizeof (float) * size);
|
safe_read((void *) params, sizeof (GLfloat) * size);
|
||||||
|
|
||||||
// Release Proxy
|
// Release Proxy
|
||||||
end_proxy_call();
|
end_proxy_call();
|
||||||
@ -863,7 +883,7 @@ CALL(48, glGetFloatv, void, (GLenum pname, GLfloat *params)) {
|
|||||||
// Run
|
// Run
|
||||||
glGetFloatv(pname, params);
|
glGetFloatv(pname, params);
|
||||||
// Return Value
|
// Return Value
|
||||||
safe_write((void *) params, sizeof (float) * size);
|
safe_write((void *) params, sizeof (GLfloat) * size);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1076,3 +1096,38 @@ CALL(58, glIsEnabled, GLboolean, (GLenum cap)) {
|
|||||||
write_int((uint32_t) ret);
|
write_int((uint32_t) ret);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int get_glGetIntegerv_params_size(GLenum pname) {
|
||||||
|
switch (pname) {
|
||||||
|
case GL_UNPACK_ALIGNMENT: {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
PROXY_ERR("Inavlid glGetIntegerv Property: %u", pname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CALL(61, glGetIntegerv, void, (GLenum pname, GLint *params)) {
|
||||||
|
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||||
|
// Lock Proxy
|
||||||
|
start_proxy_call();
|
||||||
|
|
||||||
|
// Arguments
|
||||||
|
write_int((uint32_t) pname);
|
||||||
|
|
||||||
|
// Get Return Value
|
||||||
|
int size = get_glGetIntegerv_params_size(pname);
|
||||||
|
safe_read((void *) params, sizeof (GLint) * size);
|
||||||
|
|
||||||
|
// Release Proxy
|
||||||
|
end_proxy_call();
|
||||||
|
#else
|
||||||
|
GLenum pname = (GLenum) read_int();
|
||||||
|
int size = get_glGetIntegerv_params_size(pname);
|
||||||
|
GLint params[size];
|
||||||
|
// Run
|
||||||
|
glGetIntegerv(pname, params);
|
||||||
|
// Return Value
|
||||||
|
safe_write((void *) params, sizeof (GLint) * size);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user