| 158 | } // namespace |
| 159 | |
| 160 | bool ParseMemoryImageSource(const std::wstring &method, Image &output, std::wstring &normalized_method) { |
| 161 | const std::wstring candidate_method = trim_ws(method); |
| 162 | auto parts = split_csv(candidate_method); |
| 163 | Image parsed; |
| 164 | |
| 165 | if (parts.size() >= 3) { |
| 166 | if (parts.size() != 3 && parts.size() != 4) { |
| 167 | return false; |
| 168 | } |
| 169 | byte *ptr = nullptr; |
| 170 | if (!parse_ptr(parts[0], ptr)) { |
| 171 | return false; |
| 172 | } |
| 173 | int width = 0; |
| 174 | int height = 0; |
| 175 | if (!parse_positive_int(parts[1], width) || !parse_positive_int(parts[2], height)) { |
| 176 | return false; |
| 177 | } |
| 178 | |
| 179 | std::wstring fmt = L"bgra"; |
| 180 | if (parts.size() == 4 && !parts[3].empty()) { |
| 181 | fmt = parts[3]; |
| 182 | std::transform(fmt.begin(), fmt.end(), fmt.begin(), ::towlower); |
| 183 | } |
| 184 | // 外部只提供首地址和尺寸参数,内部用 span 约束本次需要读取的字节范围。 |
| 185 | const auto bytesPerPixel = fmt == L"bgr" ? 3 : 4; |
| 186 | const auto rawBytes = static_cast<size_t>(width) * static_cast<size_t>(height) * bytesPerPixel; |
| 187 | if (!copy_raw_image({reinterpret_cast<const std::byte *>(ptr), rawBytes}, width, height, fmt, parsed)) { |
| 188 | return false; |
| 189 | } |
| 190 | output = parsed; |
| 191 | normalized_method = candidate_method; |
| 192 | return true; |
| 193 | } |
| 194 | |
| 195 | byte *ptr = nullptr; |
| 196 | if (!parse_ptr(candidate_method, ptr)) { |
| 197 | return false; |
| 198 | } |
| 199 | if (!read_bmp_image(reinterpret_cast<const std::byte *>(ptr), parsed)) { |
| 200 | return false; |
| 201 | } |
| 202 | output = parsed; |
| 203 | normalized_method = candidate_method; |
| 204 | return true; |
| 205 | } |
| 206 | |
| 207 | } // namespace op::capture |
| 208 |
no test coverage detected