Skip to content

Commit

Permalink
Merge pull request #1310 from alicevision/mug/imageCaching
Browse files Browse the repository at this point in the history
[image] New image cache
  • Loading branch information
fabiencastan authored Apr 13, 2023
2 parents e97ba3a + 1e1c7cd commit f3edd8a
Show file tree
Hide file tree
Showing 15 changed files with 1,033 additions and 82 deletions.
13 changes: 8 additions & 5 deletions src/aliceVision/image/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ set(image_files_headers
Rgb.hpp
Sampler.hpp
cache.hpp
ImageCache.hpp
)

# Sources
Expand All @@ -32,6 +33,7 @@ set(image_files_sources
io.cpp
imageAlgo.cpp
cache.cpp
ImageCache.cpp
)

alicevision_add_library(aliceVision_image
Expand All @@ -52,8 +54,9 @@ alicevision_add_library(aliceVision_image
install(FILES ./share/aliceVision/config.ocio DESTINATION ${CMAKE_INSTALL_DATADIR}/aliceVision)

# Unit tests
alicevision_add_test(image_test.cpp NAME "image" LINKS aliceVision_image)
alicevision_add_test(io_test.cpp NAME "image_io" LINKS aliceVision_image)
alicevision_add_test(drawing_test.cpp NAME "image_drawing" LINKS aliceVision_image)
alicevision_add_test(filtering_test.cpp NAME "image_filtering" LINKS aliceVision_image)
alicevision_add_test(resampling_test.cpp NAME "image_resampling" LINKS aliceVision_image)
alicevision_add_test(image_test.cpp NAME "image" LINKS aliceVision_image)
alicevision_add_test(io_test.cpp NAME "image_io" LINKS aliceVision_image)
alicevision_add_test(drawing_test.cpp NAME "image_drawing" LINKS aliceVision_image)
alicevision_add_test(filtering_test.cpp NAME "image_filtering" LINKS aliceVision_image)
alicevision_add_test(resampling_test.cpp NAME "image_resampling" LINKS aliceVision_image)
alicevision_add_test(imageCaching_test.cpp NAME "image_caching" LINKS aliceVision_image)
12 changes: 12 additions & 0 deletions src/aliceVision/image/Image.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,18 @@ namespace aliceVision
return sizeof( Tpixel );
}

/**
* @brief Retrieve the size in byte of the image
* @return size of the image (in byte)
* @note We use unsigned long long integers to avoid issues with large images, which can exceed several GB.
*/
inline unsigned long long int MemorySize() const
{
return static_cast<unsigned long long int>(Width()) *
static_cast<unsigned long long int>(Height()) *
static_cast<unsigned long long int>(Depth());
}


/**
* @brief Return the number of channels
Expand Down
161 changes: 161 additions & 0 deletions src/aliceVision/image/ImageCache.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
// This file is part of the AliceVision project.
// Copyright (c) 2022 AliceVision contributors.
// This Source Code Form is subject to the terms of the Mozilla Public License,
// v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.

#include "ImageCache.hpp"

#include <aliceVision/system/Logger.hpp>


namespace aliceVision {
namespace image {

CacheValue::CacheValue()
{
}

CacheValue CacheValue::wrap(std::shared_ptr<Image<unsigned char>> img)
{
CacheValue value;
value.imgUChar = img;
return value;
}

CacheValue CacheValue::wrap(std::shared_ptr<Image<float>> img)
{
CacheValue value;
value.imgFloat = img;
return value;
}

CacheValue CacheValue::wrap(std::shared_ptr<Image<RGBColor>> img)
{
CacheValue value;
value.imgRGB = img;
return value;
}

CacheValue CacheValue::wrap(std::shared_ptr<Image<RGBfColor>> img)
{
CacheValue value;
value.imgRGBf = img;
return value;
}

CacheValue CacheValue::wrap(std::shared_ptr<Image<RGBAColor>> img)
{
CacheValue value;
value.imgRGBA = img;
return value;
}

CacheValue CacheValue::wrap(std::shared_ptr<Image<RGBAfColor>> img)
{
CacheValue value;
value.imgRGBAf = img;
return value;
}

int CacheValue::useCount() const
{
if (imgUChar)
{
return imgUChar.use_count();
}
if (imgFloat)
{
return imgFloat.use_count();
}
if (imgRGB)
{
return imgRGB.use_count();
}
if (imgRGBf)
{
return imgRGBf.use_count();
}
if (imgRGBA)
{
return imgRGBA.use_count();
}
if (imgRGBAf)
{
return imgRGBAf.use_count();
}
return 0;
}

unsigned long long int CacheValue::memorySize() const
{
if (imgUChar)
{
return imgUChar->MemorySize();
}
if (imgFloat)
{
return imgFloat->MemorySize();
}
if (imgRGB)
{
return imgRGB->MemorySize();
}
if (imgRGBf)
{
return imgRGBf->MemorySize();
}
if (imgRGBA)
{
return imgRGBA->MemorySize();
}
if (imgRGBAf)
{
return imgRGBAf->MemorySize();
}
return 0;
}

ImageCache::ImageCache(float capacity_MiB, float maxSize_MiB, const ImageReadOptions& options) :
_info(capacity_MiB, maxSize_MiB),
_options(options)
{
}

ImageCache::~ImageCache()
{
}

std::string ImageCache::toString() const
{
std::string description = "Image cache content (LRU to MRU): ";

for (const CacheKey& key : _keys)
{
std::string keyDesc = key.filename +
", nbChannels: " + std::to_string(key.nbChannels) +
", typeDesc: " + std::to_string(key.typeDesc) +
", downscaleLevel: " + std::to_string(key.downscaleLevel) +
", usages: " + std::to_string(_imagePtrs.at(key).useCount()) +
", size: " + std::to_string(_imagePtrs.at(key).memorySize());
description += "\n * " + keyDesc;
}

std::string memUsageDesc = "\nMemory usage: "
"\n * capacity: " + std::to_string(_info.capacity) +
"\n * max size: " + std::to_string(_info.maxSize) +
"\n * nb images: " + std::to_string(_info.nbImages) +
"\n * content size: " + std::to_string(_info.contentSize);
description += memUsageDesc;

std::string statsDesc = "\nUsage statistics: "
"\n * nb load from disk: " + std::to_string(_info.nbLoadFromDisk) +
"\n * nb load from cache: " + std::to_string(_info.nbLoadFromCache) +
"\n * nb remove unused: " + std::to_string(_info.nbRemoveUnused);
description += statsDesc;

return description;
}

} // namespace image
} // namespace aliceVision
Loading

0 comments on commit f3edd8a

Please sign in to comment.