Skip to content

Commit d0af24f

Browse files
committed
feat(dng): load thumbnail images again, but resize to display window
1 parent 810959a commit d0af24f

File tree

5 files changed

+35
-16
lines changed

5 files changed

+35
-16
lines changed

include/tev/imageio/ImageLoader.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,11 @@ class ImageLoader {
186186
size_t numChannels, const nanogui::Vector2i& size, EPixelFormat format, EPixelFormat desiredFormat, std::string_view layer
187187
);
188188

189-
static Task<void> resizeChannelsAsync(std::span<const Channel> srcChannels, std::vector<Channel>& dstChannels, int priority);
190-
static Task<void> resizeImageData(ImageData& resultData, const nanogui::Vector2i& targetSize, int priority);
189+
static Task<void> resizeChannelsAsync(
190+
std::span<const Channel> srcChannels, std::vector<Channel>& dstChannels, const std::optional<Box2i>& dstBox, int priority
191+
);
192+
static Task<void>
193+
resizeImageData(ImageData& resultData, const nanogui::Vector2i& targetSize, const std::optional<Box2i>& targetBox, int priority);
191194
};
192195

193196
} // namespace tev

src/Image.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,10 @@ Task<void> ImageData::matchColorsAndSizeOf(const ImageData& other, int priority)
214214

215215
co_await applyColorConversion(inverse(other.toRec709) * toRec709, priority);
216216
if (!other.channels.empty()) {
217-
co_await ImageLoader::resizeImageData(*this, other.channels.front().size(), priority);
217+
optional<Box2i> targetBox = other.displayWindow.isValid() && other.dataWindow.isValid() ?
218+
optional{other.displayWindow.translate(-other.dataWindow.min)} :
219+
nullopt;
220+
co_await ImageLoader::resizeImageData(*this, other.channels.front().size(), targetBox, priority);
218221
}
219222
}
220223

src/imageio/GainMap.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ Task<void> preprocessAndApplyAppleGainMap(
101101

102102
const auto size = imageChannels.front()->size();
103103

104-
co_await ImageLoader::resizeImageData(gainMap, size, priority);
104+
co_await ImageLoader::resizeImageData(gainMap, size, nullopt, priority);
105105

106106
// Re-fetch channels after resize
107107
gainMapChannels = getRgbOrLuminanceChannels(gainMap);
@@ -227,7 +227,7 @@ Task<void> preprocessAndApplyIsoGainMap(
227227

228228
const auto size = imageChannels.front()->size();
229229

230-
co_await ImageLoader::resizeImageData(gainMap, size, priority);
230+
co_await ImageLoader::resizeImageData(gainMap, size, nullopt, priority);
231231

232232
// Re-fetch channels after resize
233233
gainMapChannels = getRgbOrLuminanceChannels(gainMap);

src/imageio/ImageLoader.cpp

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,9 @@ vector<Channel>
225225
return channels;
226226
}
227227

228-
Task<void> ImageLoader::resizeChannelsAsync(span<const Channel> srcChannels, vector<Channel>& dstChannels, int priority) {
228+
Task<void> ImageLoader::resizeChannelsAsync(
229+
span<const Channel> srcChannels, vector<Channel>& dstChannels, const optional<Box2i>& dstArea, int priority
230+
) {
229231
TEV_ASSERT(srcChannels.size() == dstChannels.size(), "Number of source and destination channels must match.");
230232
if (srcChannels.empty()) {
231233
co_return;
@@ -235,23 +237,36 @@ Task<void> ImageLoader::resizeChannelsAsync(span<const Channel> srcChannels, vec
235237
const Vector2i targetSize = dstChannels.front().size();
236238
const int numChannels = (int)srcChannels.size();
237239

240+
const Box2i box = dstArea.value_or(Box2i{Vector2i(0, 0), targetSize});
241+
238242
for (int i = 1; i < numChannels; ++i) {
239243
TEV_ASSERT(srcChannels[i].size() == size, "Source channels' size must match.");
240244
TEV_ASSERT(dstChannels[i].size() == targetSize, "Destination channels' size must match.");
241245
}
242246

243247
const size_t numSamples = (size_t)targetSize.x() * targetSize.y() * numChannels;
244-
const float scaleX = (float)size.x() / targetSize.x();
245-
const float scaleY = (float)size.y() / targetSize.y();
248+
249+
const float scaleX = (float)size.x() / box.size().x();
250+
const float scaleY = (float)size.y() / box.size().y();
246251

247252
co_await ThreadPool::global().parallelForAsync<int>(
248253
0,
249254
targetSize.y(),
250255
numSamples,
251256
[&](int dstY) {
252257
for (int dstX = 0; dstX < targetSize.x(); ++dstX) {
253-
const float srcX = (dstX + 0.5f) * scaleX - 0.5f;
254-
const float srcY = (dstY + 0.5f) * scaleY - 0.5f;
258+
const size_t dstIdx = dstY * (size_t)targetSize.x() + dstX;
259+
260+
if (dstX < box.min.x() || dstX >= box.max.x() || dstY < box.min.y() || dstY >= box.max.y()) {
261+
for (int c = 0; c < numChannels; ++c) {
262+
dstChannels[c].setAt(dstIdx, 0.0f);
263+
}
264+
265+
continue;
266+
}
267+
268+
const float srcX = ((dstX - box.min.x()) + 0.5f) * scaleX - 0.5f;
269+
const float srcY = ((dstY - box.min.y()) + 0.5f) * scaleY - 0.5f;
255270

256271
const int x0 = std::max((int)floor(srcX), 0);
257272
const int y0 = std::max((int)floor(srcY), 0);
@@ -268,8 +283,6 @@ Task<void> ImageLoader::resizeChannelsAsync(span<const Channel> srcChannels, vec
268283
const float w10 = wx0 * wy1;
269284
const float w11 = wx1 * wy1;
270285

271-
const size_t dstIdx = dstY * (size_t)targetSize.x() + dstX;
272-
273286
const size_t srcIdx00 = y0 * (size_t)size.x() + x0;
274287
const size_t srcIdx01 = y0 * (size_t)size.x() + x1;
275288
const size_t srcIdx10 = y1 * (size_t)size.x() + x0;
@@ -289,7 +302,7 @@ Task<void> ImageLoader::resizeChannelsAsync(span<const Channel> srcChannels, vec
289302
);
290303
}
291304

292-
Task<void> ImageLoader::resizeImageData(ImageData& resultData, const Vector2i& targetSize, int priority) {
305+
Task<void> ImageLoader::resizeImageData(ImageData& resultData, const Vector2i& targetSize, const optional<Box2i>& targetArea, int priority) {
293306
const Vector2i size = resultData.channels.front().size();
294307
if (size == targetSize) {
295308
co_return;
@@ -302,7 +315,7 @@ Task<void> ImageLoader::resizeImageData(ImageData& resultData, const Vector2i& t
302315
resultData.channels.emplace_back(c.name(), targetSize, c.pixelFormat(), c.desiredPixelFormat());
303316
}
304317

305-
co_await resizeChannelsAsync(prevChannels, resultData.channels, priority);
318+
co_await resizeChannelsAsync(prevChannels, resultData.channels, targetArea, priority);
306319
};
307320

308321
} // namespace tev

src/imageio/TiffImageLoader.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2547,7 +2547,7 @@ Task<ImageData>
25472547

25482548
photometric = isDng ? PHOTOMETRIC_LINEAR_RAW : PHOTOMETRIC_RGB;
25492549

2550-
resultData.channels.front().setName(Channel::joinIfNonempty(partName, "cfa"));
2550+
resultData.channels.front().setName(Channel::joinIfNonempty(partName, "cfa.L"));
25512551
resultData.channels.insert(
25522552
resultData.channels.begin(), make_move_iterator(rgbaChannels.begin()), make_move_iterator(rgbaChannels.end())
25532553
);
@@ -2696,7 +2696,7 @@ Task<vector<ImageData>> TiffImageLoader::load(istream& iStream, const fs::path&
26962696
// DNGs often come with multiple thumbnail images that act as a loading preview in photo editing software. Uninteresting for
26972697
// tev to load, except for the main IFD's orientation tag, which is authorative.
26982698
if (isThumbnail(type)) {
2699-
co_return;
2699+
// co_return;
27002700
}
27012701

27022702
name = dngSubFileTypeToString(type);

0 commit comments

Comments
 (0)