| 86 | } |
| 87 | |
| 88 | std::optional<cv::Mat> ScreencapHelper::decode_raw(const std::string& buffer) |
| 89 | { |
| 90 | if (buffer.size() < 8) { |
| 91 | return std::nullopt; |
| 92 | } |
| 93 | |
| 94 | const uint8_t* data = reinterpret_cast<const uint8_t*>(buffer.data()); |
| 95 | uint32_t im_width = 0, im_height = 0; |
| 96 | memcpy(&im_width, data, 4); |
| 97 | memcpy(&im_height, data + 4, 4); |
| 98 | |
| 99 | size_t size = 4ull * im_width * im_height; |
| 100 | |
| 101 | if (buffer.size() < size) { |
| 102 | return std::nullopt; |
| 103 | } |
| 104 | |
| 105 | size_t header_size = buffer.size() - size; |
| 106 | const uint8_t* im_data = data + header_size; |
| 107 | |
| 108 | cv::Mat temp(im_height, im_width, CV_8UC4, const_cast<uint8_t*>(im_data)); |
| 109 | if (temp.empty()) { |
| 110 | return std::nullopt; |
| 111 | } |
| 112 | |
| 113 | const auto& br = *(temp.end<cv::Vec4b>() - 1); |
| 114 | if (br[3] != 255) { // only check alpha |
| 115 | return std::nullopt; |
| 116 | } |
| 117 | cv::cvtColor(temp, temp, cv::COLOR_RGBA2BGR); |
| 118 | return temp.clone(); // temp只是引用data, 需要clone确保数据拥有所有权 |
| 119 | } |
| 120 | |
| 121 | std::optional<cv::Mat> ScreencapHelper::decode_gzip(const std::string& buffer) |
| 122 | { |