| 71 | static std::shared_ptr<Image> create(uint32_t width, uint32_t height) { return std::make_shared<Image>(width, height); } |
| 72 | |
| 73 | static std::shared_ptr<Image> loadFromFile(const std::filesystem::path& path) |
| 74 | { |
| 75 | FREE_IMAGE_FORMAT fifFormat = FIF_UNKNOWN; |
| 76 | |
| 77 | auto pathStr = path.string(); |
| 78 | |
| 79 | // Determine file format. |
| 80 | fifFormat = FreeImage_GetFileType(pathStr.c_str(), 0); |
| 81 | if (fifFormat == FIF_UNKNOWN) |
| 82 | fifFormat = FreeImage_GetFIFFromFilename(pathStr.c_str()); |
| 83 | if (fifFormat == FIF_UNKNOWN) |
| 84 | throw std::runtime_error("Unknown image format"); |
| 85 | if (!FreeImage_FIFSupportsReading(fifFormat)) |
| 86 | throw std::runtime_error("Unsupported image format"); |
| 87 | |
| 88 | // Read image. |
| 89 | FIBITMAP* srcBitmap = FreeImage_Load(fifFormat, pathStr.c_str()); |
| 90 | if (!srcBitmap) |
| 91 | throw std::runtime_error("Cannot read image"); |
| 92 | |
| 93 | // Convert to RGBA32F. |
| 94 | FIBITMAP* floatBitmap = FreeImage_ConvertToRGBAF(srcBitmap); |
| 95 | FreeImage_Unload(srcBitmap); |
| 96 | if (!floatBitmap) |
| 97 | throw std::runtime_error("Cannot convert to RGBA float format"); |
| 98 | |
| 99 | // Create image. |
| 100 | auto image = create(FreeImage_GetWidth(floatBitmap), FreeImage_GetHeight(floatBitmap)); |
| 101 | int bytesPerPixel = 4 * sizeof(float); |
| 102 | FreeImage_ConvertToRawBits( |
| 103 | reinterpret_cast<BYTE*>(image->getData()), |
| 104 | floatBitmap, |
| 105 | bytesPerPixel * image->getWidth(), |
| 106 | bytesPerPixel * 8, |
| 107 | FI_RGBA_RED_MASK, |
| 108 | FI_RGBA_GREEN_MASK, |
| 109 | FI_RGBA_BLUE_MASK, |
| 110 | true |
| 111 | ); |
| 112 | FreeImage_Unload(floatBitmap); |
| 113 | |
| 114 | return image; |
| 115 | } |
| 116 | |
| 117 | void saveToFile(const std::filesystem::path& path, bool writeAlpha = true) const |
| 118 | { |