| 115 | } |
| 116 | |
| 117 | void saveToFile(const std::filesystem::path& path, bool writeAlpha = true) const |
| 118 | { |
| 119 | FREE_IMAGE_FORMAT fifFormat = FIF_UNKNOWN; |
| 120 | |
| 121 | auto pathStr = path.string(); |
| 122 | |
| 123 | // Determine file format. |
| 124 | fifFormat = FreeImage_GetFIFFromFilename(pathStr.c_str()); |
| 125 | if (fifFormat == FIF_UNKNOWN) |
| 126 | throw std::runtime_error("Unknown image format"); |
| 127 | if (!FreeImage_FIFSupportsWriting(fifFormat)) |
| 128 | throw std::runtime_error("Unsupported image format"); |
| 129 | |
| 130 | bool writeFloat = fifFormat == FIF_EXR || fifFormat == FIF_PFM || fifFormat == FIF_HDR; |
| 131 | if (fifFormat != FIF_EXR && fifFormat != FIF_PNG) |
| 132 | writeAlpha = false; |
| 133 | |
| 134 | // Create bitmap. |
| 135 | FIBITMAP* bitmap; |
| 136 | const float* src = getData(); |
| 137 | if (writeFloat) |
| 138 | { |
| 139 | bitmap = FreeImage_AllocateT(writeAlpha ? FIT_RGBAF : FIT_RGBF, mWidth, mHeight); |
| 140 | for (uint32_t y = 0; y < mHeight; y++) |
| 141 | { |
| 142 | float* dst = reinterpret_cast<float*>(FreeImage_GetScanLine(bitmap, mHeight - y - 1)); |
| 143 | if (writeAlpha) |
| 144 | { |
| 145 | std::memcpy(dst, src, mWidth * 4 * sizeof(float)); |
| 146 | src += mWidth * 4; |
| 147 | } |
| 148 | else |
| 149 | { |
| 150 | for (uint32_t x = 0; x < mWidth; ++x) |
| 151 | { |
| 152 | dst[0] = src[0]; |
| 153 | dst[1] = src[1]; |
| 154 | dst[2] = src[2]; |
| 155 | dst += 3; |
| 156 | src += 4; |
| 157 | } |
| 158 | } |
| 159 | } |
| 160 | } |
| 161 | else |
| 162 | { |
| 163 | bitmap = FreeImage_Allocate(mWidth, mHeight, writeAlpha ? 32 : 24); |
| 164 | for (uint32_t y = 0; y < mHeight; y++) |
| 165 | { |
| 166 | uint8_t* dst = reinterpret_cast<uint8_t*>(FreeImage_GetScanLine(bitmap, mHeight - y - 1)); |
| 167 | for (uint32_t x = 0; x < mWidth; ++x) |
| 168 | { |
| 169 | dst[2] = clamp(int(src[0] * 255.f), 0, 255); |
| 170 | dst[1] = clamp(int(src[1] * 255.f), 0, 255); |
| 171 | dst[0] = clamp(int(src[2] * 255.f), 0, 255); |
| 172 | if (writeAlpha) |
| 173 | dst[3] = clamp(int(src[3] * 255.f), 0, 255); |
| 174 | dst += writeAlpha ? 4 : 3; |
no test coverage detected