Fix bug incorrectly blending cursor image
This commit is contained in:
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user