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

Reply via email to