I had a few minutes to experiment with this, and I think this is the simplest
roll-your-own RAII approach:
struct TileReleaser {
TileReleaser(ImageCache& ic) : ic(ic) {}
void operator()(ImageCache::Tile* tile) { ic.release_tile(tile); }
private:
ImageCache& ic;
};
using TileHolder = std::unique_ptr<ImageCache::Tile, TileReleaser>;
Example use:
{
// construct a unique_ptr that will release the tile upon destruction
TileHolder tile(imagecache->get_tile(filename, 0, 0, 0, 0, 0),
TileReleaser(*imagecache));
// example of using the pointer via get()
TypeDesc format;
void* pels = imagecache->tile_pixels(tile.get(), format);
// The tile will automatically release when it exits scope
}
Though, as I said before, it's extremely rare that ordinary developers need to
use the get_tile/release_tile API.
> On Oct 13, 2020, at 4:52 PM, Larry Gritz <[email protected]> wrote:
>
>
>
>> On Oct 13, 2020, at 2:15 PM, Arman Garakani <[email protected]
>> <mailto:[email protected]>> wrote:
>>
>> 2. Not calling release: got it. I am sure you have thought about a RAII way
>> of dealing with this.
>
> I hadn't really thought about this, but I think it would be fairly trivial,
> like this sketch (caveat: I'm just typing this off the top of my head):
>
> struct TileHolder {
> ImageCache* ic;
> ImageCache::Tile* tile;
>
> // construct from pointers to IC and Tile (presumably returned by
> ic->get_tile())
> TileHolder(ImageCache* ic, ImageCache::Tile* tile)
> : ic(ic), tile(tile) {}
>
> // destructor releases the tile
> ~TileHolder() { ic->release_tile(tile); }
>
> // operator() returns the Tile*
> ImageCache::Tile* operator()() const { return tile; }
> };
>
> then use something like:
>
> TileHolder th(ic, ic->get_tile(filename, subimage, miplevel, x, y, z));
> ...
> roi = ic->tile_roi(th());
> ...
> // When th exists scope, ic->release_tile(th()) is automatically called
>
> Would something like this be generally handy for me to add to imagecache.h to
> make it easier to juggle the Tile*'s?
>
> The reason I didn't bother is that the Tile* interface is very specialized
> and advanced. I didn't expect people to directly use it except in very rare
> circumstances. The usual way to interact with ImageCache is either through
> get_pixels (which copies whatever pixels you need to your buffer, without
> needing to worry about how the tiles work at all), or by using ImageBuf
> (which looks like an image, has pixel Iterator classes to traverse them, and
> hides all the underlying ImageCache mechanism for large images).
>
>
>>
>> 3. Number of sub images:
>>
>> The takeaway is that get_imagespec returns the spec for current sub
>> image. For multi-image files, calling it repeatedly returns the current sub
>> image count. Hence calling it repeatedly, gets the number of sub images. Got
>> it.
>
> It does, but you can ask for the number of subimages directly (as in my
> explanation), without having to copy spec after spec until you fail.
>
>
>
>> The issue that I have is time stamps on a multi-image tif aka tif stack. I
>> know there are time stamp information for every image. However I can not
>> find a way to fetch them through the API. I could use the sub image index.
>> If I could get duration or FramePerSecond ( floating point or a rational
>> number ). Am I missing the API ? Does it make sense to support ?
>
> Yes, like if you wanted the DateTime for each subimage, you could get it with:
>
> ustring datetime;
> ic->get_image_info (filename, subimage, /*miplevel=*/ 0,
> ustring("DateTime"), OIIO::TypeString, &datetime);
>
> This is assuming you want to use the ImageCache approach at all. Do you need
> unlimited numbers of high-res images open all at the same time, but using a
> small and fixed amount of memory and without having to keep track of any
> allocations or open file handles? That's what IC is supposed to be for.
>
> If you are primarily accessing just one or a few images/subimages at any one
> time, it's probably easier to just use the ImageBuf interface:
>
> // Make an ImageBuf for a file (by default, first subimage)
> ImageBuf buf(filename);
>
> // How many subimages does this image have?
> int nsubimages = buf.nsubimages();
>
> // Point to a different subimage
> buf.reset(filename, subimage);
>
> // Directly ask for some metadata about that subimage
> std::string datetime = buf.spec().get_string_attribute("DateTime");
>
> // Copy some pixels to my area, with data type conversion
> buf.get_pixels(roi, TypeFloat, my_float_ptr);
>
>
> --
> Larry Gritz
> [email protected] <mailto:[email protected]>
>
>
>
>
> _______________________________________________
> Oiio-dev mailing list
> [email protected]
> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
--
Larry Gritz
[email protected]
_______________________________________________
Oiio-dev mailing list
[email protected]
http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org