Re: RAII
1. Presumably internally, there are calls to tile release. RAII
improves exception safety because the destructor will get called.
2. The other option is to return a TileHolder
Our main use-case would benefit from ImageBuf interface. Thanks for suggesting
it.
-Arman
> On Oct 13, 2020, at 6:07 PM, Larry Gritz <[email protected]> wrote:
>
> 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]
>> <mailto:[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] <mailto:[email protected]>
>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>
> --
> Larry Gritz
> [email protected] <mailto:[email protected]>
>
>
>
>
> _______________________________________________
> Oiio-dev mailing list
> [email protected]
> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
_______________________________________________
Oiio-dev mailing list
[email protected]
http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org