| 156 | } |
| 157 | |
| 158 | Vec2U ImageMetadataDatabase::calculateImageSize(AssetPath const& path) const { |
| 159 | // Carefully calculate an image's size while trying not to actually load it. |
| 160 | // In error cases, this will fall back to calling Assets::image, so that image |
| 161 | // can possibly produce a missing image asset or properly report the error. |
| 162 | |
| 163 | auto assets = Root::singleton().assets(); |
| 164 | |
| 165 | auto fallback = [&assets, &path]() { |
| 166 | return assets->image(path)->size(); |
| 167 | }; |
| 168 | |
| 169 | if (!assets->assetExists(path.basePath)) { |
| 170 | return fallback(); |
| 171 | } |
| 172 | |
| 173 | Vec2U imageSize; |
| 174 | if (path.subPath) { |
| 175 | auto frames = assets->imageFrames(path.basePath); |
| 176 | if (!frames) |
| 177 | return fallback(); |
| 178 | |
| 179 | if (auto rect = frames->getRect(*path.subPath)) |
| 180 | imageSize = rect->size(); |
| 181 | else |
| 182 | return fallback(); |
| 183 | } else { |
| 184 | // We ensure that the base image size is cached even when given directives, |
| 185 | // so we don't have to call Image::readPngMetadata on the same file more |
| 186 | // than once. |
| 187 | MutexLocker locker(m_mutex); |
| 188 | if (auto size = m_sizeCache.ptr(path.basePath)) { |
| 189 | imageSize = *size; |
| 190 | } else { |
| 191 | locker.unlock(); |
| 192 | auto file = assets->openFile(path.basePath); |
| 193 | if (Image::isPng(file)) |
| 194 | imageSize = get<0>(Image::readPngMetadata(file)); |
| 195 | else |
| 196 | imageSize = fallback(); |
| 197 | locker.lock(); |
| 198 | m_sizeCache.set(path.basePath, imageSize); |
| 199 | } |
| 200 | } |
| 201 | |
| 202 | struct OperationSizeAdjust { |
| 203 | Vec2U& imageSize; |
| 204 | bool hasError; |
| 205 | |
| 206 | OperationSizeAdjust(Vec2U& size) : imageSize(size), hasError(false) {}; |
| 207 | |
| 208 | void operator()(NullImageOperation const&) {} |
| 209 | |
| 210 | void operator()(ErrorImageOperation const&) {} |
| 211 | |
| 212 | void operator()(HueShiftImageOperation const&) {} |
| 213 | |
| 214 | void operator()(SaturationShiftImageOperation const&) {} |
| 215 |
nothing calls this directly
no test coverage detected