Fix bug incorrectly blending cursor image

This commit is contained in:
loki
2020-03-17 22:17:28 +01:00
parent 5bbca8f517
commit e571b29868
2 changed files with 48 additions and 27 deletions

View File

@@ -122,22 +122,28 @@ void blend_cursor_monochrome(const cursor_t &cursor, img_t &img) {
int width = cursor.shape_info.Width;
int pitch = cursor.shape_info.Pitch;
// img cursor.y < 0, skip parts of the cursor.img_data
auto cursor_skip_y = std::min(0, cursor.y);
auto cursor_skip_x = std::min(0, cursor.x);
auto img_skip_y = std::max(0, cursor.y);
auto img_skip_x = std::max(0, cursor.x);
// img cursor.{x,y} < 0, skip parts of the cursor.img_data
auto cursor_skip_y = -std::min(0, cursor.y);
auto cursor_skip_x = -std::min(0, cursor.x);
if(cursor_skip_y > height || cursor_skip_x > width) {
// img cursor.{x,y} > img.{x,y}, truncate parts of the cursor.img_data
auto cursor_truncate_y = std::max(0, cursor.y - img.height);
auto cursor_truncate_x = std::max(0, cursor.x - img.width);
auto cursor_width = width - cursor_skip_x - cursor_truncate_x;
auto cursor_height = height - cursor_skip_y - cursor_truncate_y;
if(cursor_height > height || cursor_width > width) {
return;
}
height -= cursor_skip_y;
width -= cursor_skip_x;
auto img_skip_y = std::max(0, cursor.y);
auto img_skip_x = std::max(0, cursor.x);
auto cursor_img_data = cursor.img_data.data() + cursor_skip_y * pitch;
int delta_height = std::min(height, std::max(0, img.height - img_skip_y));
int delta_width = std::min(width, std::max(0, img.width - img_skip_x));
int delta_height = std::min(cursor_height - cursor_truncate_y, std::max(0, img.height - img_skip_y));
int delta_width = std::min(cursor_width - cursor_truncate_x, std::max(0, img.width - img_skip_x));
auto pixels_per_byte = width / pitch;
auto bytes_per_row = delta_width / pixels_per_byte;
@@ -149,11 +155,11 @@ void blend_cursor_monochrome(const cursor_t &cursor, img_t &img) {
auto img_pixel_p = &img_data[(i + img_skip_y) * (img.row_pitch / img.pixel_pitch) + img_skip_x];
auto skip_y = cursor_skip_y;
auto skip_x = cursor_skip_x;
for(int x = 0; x < bytes_per_row; ++x) {
for(auto bit = 0u; bit < 8; ++bit) {
if(skip_y > 0) {
--skip_y;
if(skip_x > 0) {
--skip_x;
continue;
}
@@ -179,26 +185,32 @@ void blend_cursor_color(const cursor_t &cursor, img_t &img) {
int pitch = cursor.shape_info.Pitch;
// img cursor.y < 0, skip parts of the cursor.img_data
auto cursor_skip_y = std::min(0, cursor.y);
auto cursor_skip_x = std::min(0, cursor.x);
auto cursor_skip_y = -std::min(0, cursor.y);
auto cursor_skip_x = -std::min(0, cursor.x);
// img cursor.{x,y} > img.{x,y}, truncate parts of the cursor.img_data
auto cursor_truncate_y = std::max(0, cursor.y - img.height);
auto cursor_truncate_x = std::max(0, cursor.x - img.width);
auto img_skip_y = std::max(0, cursor.y);
auto img_skip_x = std::max(0, cursor.x);
if(cursor_skip_y > height || cursor_skip_x > width) {
auto cursor_width = width - cursor_skip_x - cursor_truncate_x;
auto cursor_height = height - cursor_skip_y - cursor_truncate_y;
if(cursor_height > height || cursor_width > width) {
return;
}
height -= cursor_skip_y;
width -= cursor_skip_x;
auto cursor_img_data = (int*)&cursor.img_data[cursor_skip_y * pitch];
int delta_height = std::min(height, std::max(0, img.height - img_skip_y));
int delta_width = std::min(width, std::max(0, img.width - img_skip_x));
int delta_height = std::min(cursor_height - cursor_truncate_y, std::max(0, img.height - img_skip_y));
int delta_width = std::min(cursor_width - cursor_truncate_x, std::max(0, img.width - img_skip_x));
auto img_data = (int*)img.data;
for(int i = 0; i < delta_height; ++i) {
auto cursor_begin = &cursor_img_data[i * width + cursor_skip_x];
auto cursor_begin = &cursor_img_data[i * cursor.shape_info.Width + cursor_skip_x];
auto cursor_end = &cursor_begin[delta_width];
auto img_pixel_p = &img_data[(i + img_skip_y) * (img.row_pitch / img.pixel_pitch) + img_skip_x];

View File

@@ -21,6 +21,15 @@ using asio::ip::udp;
using namespace std::literals;
namespace stream {
//FIXME: Quick and dirty workaround for bug in MinGW 9.3 causing a linker error when using std::to_string
template<class T>
std::string to_string(T && t) {
std::stringstream ss;
ss << std::forward<T>(t);
return ss.str();
}
constexpr auto RTSP_SETUP_PORT = 48010;
void free_msg(PRTSP_MESSAGE msg) {
@@ -222,7 +231,7 @@ void cmd_option(rtsp_server_t *server, net::peer_t peer, msg_t&& req) {
// I know these string literals will not be modified
option.option = const_cast<char*>("CSeq");
auto seqn_str = std::to_string(req->sequenceNumber);
auto seqn_str = to_string(req->sequenceNumber);
option.content = const_cast<char*>(seqn_str.c_str());
respond(server->host(), peer, &option, 200, "OK", req->sequenceNumber, {});
@@ -234,7 +243,7 @@ void cmd_describe(rtsp_server_t *server, net::peer_t peer, msg_t&& req) {
// I know these string literals will not be modified
option.option = const_cast<char*>("CSeq");
auto seqn_str = std::to_string(req->sequenceNumber);
auto seqn_str = to_string(req->sequenceNumber);
option.content = const_cast<char*>(seqn_str.c_str());
std::string_view payload;
@@ -256,7 +265,7 @@ void cmd_setup(rtsp_server_t *server, net::peer_t peer, msg_t &&req) {
seqn.option = const_cast<char*>("CSeq");
auto seqn_str = std::to_string(req->sequenceNumber);
auto seqn_str = to_string(req->sequenceNumber);
seqn.content = const_cast<char*>(seqn_str.c_str());
std::string_view target { req->message.request.target };
@@ -285,7 +294,7 @@ void cmd_announce(rtsp_server_t *server, net::peer_t peer, msg_t &&req) {
// I know these string literals will not be modified
option.option = const_cast<char*>("CSeq");
auto seqn_str = std::to_string(req->sequenceNumber);
auto seqn_str = to_string(req->sequenceNumber);
option.content = const_cast<char*>(seqn_str.c_str());
if(!launch_event.peek()) {
@@ -394,7 +403,7 @@ void cmd_play(rtsp_server_t *server, net::peer_t peer, msg_t &&req) {
// I know these string literals will not be modified
option.option = const_cast<char*>("CSeq");
auto seqn_str = std::to_string(req->sequenceNumber);
auto seqn_str = to_string(req->sequenceNumber);
option.content = const_cast<char*>(seqn_str.c_str());
respond(server->host(), peer, &option, 200, "OK", req->sequenceNumber, {});
@@ -464,4 +473,4 @@ void print_msg(PRTSP_MESSAGE msg) {
BOOST_LOG(debug) << "---Begin MessageBuffer---"sv << std::endl << messageBuffer << std::endl << "---End MessageBuffer---"sv << std::endl;
}
}
}