///////////////////////////////////////////////////////
| 227 | |
| 228 | //////////////////////////////////////////////////////////// |
| 229 | bool Image::loadFromFile(const std::filesystem::path& filename) |
| 230 | { |
| 231 | #ifdef SFML_SYSTEM_ANDROID |
| 232 | |
| 233 | if (priv::getActivityStatesPtr() != nullptr) |
| 234 | { |
| 235 | priv::ResourceStream stream; |
| 236 | if (!stream.open(filename)) |
| 237 | return false; |
| 238 | return loadFromStream(stream); |
| 239 | } |
| 240 | |
| 241 | #endif |
| 242 | |
| 243 | // Set up the stb_image callbacks for the std::ifstream |
| 244 | const auto readStdIfStream = [](void* user, char* data, int size) |
| 245 | { |
| 246 | auto& file = *static_cast<std::ifstream*>(user); |
| 247 | file.read(data, size); |
| 248 | return static_cast<int>(file.gcount()); |
| 249 | }; |
| 250 | const auto skipStdIfStream = [](void* user, int size) |
| 251 | { |
| 252 | auto& file = *static_cast<std::ifstream*>(user); |
| 253 | if (!file.seekg(size, std::ios_base::cur)) |
| 254 | err() << "Failed to seek image loader std::ifstream" << std::endl; |
| 255 | }; |
| 256 | const auto eofStdIfStream = [](void* user) |
| 257 | { |
| 258 | auto& file = *static_cast<std::ifstream*>(user); |
| 259 | return static_cast<int>(file.eof()); |
| 260 | }; |
| 261 | const stbi_io_callbacks callbacks{readStdIfStream, skipStdIfStream, eofStdIfStream}; |
| 262 | |
| 263 | // Open file |
| 264 | std::ifstream file(filename, std::ios::binary); |
| 265 | if (!file.is_open()) |
| 266 | { |
| 267 | // Error, failed to open the file |
| 268 | err() << "Failed to load image\n" |
| 269 | << formatDebugPathInfo(filename) << "\nReason: " << std::strerror(errno) << std::endl; |
| 270 | return false; |
| 271 | } |
| 272 | |
| 273 | // Read a (possible) QOI magic number |
| 274 | std::array<char, 4> qoiMagicNumber{}; |
| 275 | file.read(qoiMagicNumber.data(), static_cast<std::streamsize>(qoiMagicNumber.size())); |
| 276 | |
| 277 | // Seek back to the start of the file for reading |
| 278 | file.seekg(0, std::ios::beg); |
| 279 | |
| 280 | // Read the QOI file if it's valid |
| 281 | if (isQoiMagicNumber(std::string_view(qoiMagicNumber.data(), static_cast<size_t>(file.gcount())))) |
| 282 | { |
| 283 | // Get the size of the file |
| 284 | file.seekg(0, std::ios::end); |
| 285 | const auto streamSize = static_cast<std::streamsize>(file.tellg()); |
| 286 | file.seekg(0, std::ios::beg); |
no test coverage detected