From c863db37c74c44c896c8a0994557decd805d5213 Mon Sep 17 00:00:00 2001 From: Ole Gulbrandsen Date: Wed, 17 Nov 2021 12:49:20 -0800 Subject: [PATCH] Add get_texture_info_type to query TypeDesc of arbitrary texture attributes --- src/include/OpenImageIO/imagecache.h | 7 +++++ src/include/OpenImageIO/texture.h | 8 ++++++ src/libtexture/imagecache.cpp | 42 ++++++++++++++++++++++++++++ src/libtexture/imagecache_pvt.h | 8 ++++++ src/libtexture/texture_pvt.h | 6 ++++ src/libtexture/texturesys.cpp | 29 +++++++++++++++++++ 6 files changed, 100 insertions(+) diff --git a/src/include/OpenImageIO/imagecache.h b/src/include/OpenImageIO/imagecache.h index aa6ce77fbc..dfb152eae3 100644 --- a/src/include/OpenImageIO/imagecache.h +++ b/src/include/OpenImageIO/imagecache.h @@ -657,6 +657,13 @@ class OIIO_API ImageCache { int subimage, int miplevel, ustring dataname, TypeDesc datatype, void *data) = 0; + + //Output the TypeDesc of a given attribute (if found). If not found + //we return unknown. + virtual bool get_image_info_type (ImageHandle *file, Perthread *thread_info, + int subimage, int miplevel, + ustring dataname, TypeDesc &datatype) = 0; + /// Copy the ImageSpec associated with the named image (the first /// subimage & miplevel by default, or as set by `subimage` and /// `miplevel`). diff --git a/src/include/OpenImageIO/texture.h b/src/include/OpenImageIO/texture.h index e7a8879ada..6a5ca668c7 100644 --- a/src/include/OpenImageIO/texture.h +++ b/src/include/OpenImageIO/texture.h @@ -1563,6 +1563,14 @@ class OIIO_API TextureSystem { Perthread *thread_info, int subimage, ustring dataname, TypeDesc datatype, void *data) = 0; + // Find the TypeDesc of an "Anything else" metadata + virtual bool get_texture_info_type (ustring filename, int subimage, + ustring dataname, TypeDesc &datatype) = 0; + + virtual bool get_texture_info_type (TextureHandle *texture_handle, + Perthread *thread_info, int subimage, + ustring dataname, TypeDesc &datatype) = 0; + /// Copy the ImageSpec associated with the named texture (the first /// subimage by default, or as set by `subimage`). /// diff --git a/src/libtexture/imagecache.cpp b/src/libtexture/imagecache.cpp index 9c04b313df..f0a738f013 100644 --- a/src/libtexture/imagecache.cpp +++ b/src/libtexture/imagecache.cpp @@ -2822,6 +2822,48 @@ ImageCacheImpl::get_image_info(ImageCacheFile* file, #undef ATTR_DECODE } +bool +ImageCacheImpl::get_image_info_type(ustring filename, int subimage, + int miplevel, ustring dataname, + TypeDesc& datatype) +{ + ImageCachePerThreadInfo* thread_info = get_perthread_info(); + ImageCacheFile* file = find_file(filename, thread_info, nullptr); + if (!file && dataname != s_exists) { + error("Invalid image file \"{}\"", filename); + return false; + } + return get_image_info_type(file, thread_info, subimage, miplevel, dataname, + datatype); +} + +bool +ImageCacheImpl::get_image_info_type(ImageCacheFile* file, + ImageCachePerThreadInfo* thread_info, + int subimage, int miplevel, + ustring dataname, TypeDesc& datatype) +{ + // Output the TypeDesc of a given attribute (if found). If not found + // we set it to UNKNOWN. + + ImageCacheStatistics& stats(thread_info->m_stats); + ++stats.imageinfo_queries; + file = verify_file(file, thread_info, true); + + const ImageSpec& spec(file->spec(subimage, miplevel)); + ParamValue tmpparam; + const ParamValue* p = spec.find_attribute(dataname, tmpparam); + + if (p) { + datatype = p->type(); + return true; + } + + // Does it make sense to set the type here, or should we just return + // false? + datatype.basetype = TypeDesc::UNKNOWN; + return false; +} bool diff --git a/src/libtexture/imagecache_pvt.h b/src/libtexture/imagecache_pvt.h index 2534d1e263..1a42aed920 100644 --- a/src/libtexture/imagecache_pvt.h +++ b/src/libtexture/imagecache_pvt.h @@ -842,6 +842,14 @@ class ImageCacheImpl final : public ImageCache { int subimage, int miplevel, ustring dataname, TypeDesc datatype, void* data); + virtual bool get_image_info_type(ustring filename, int subimage, + int miplevel, ustring dataname, + TypeDesc& datatype); + virtual bool get_image_info_type(ImageCacheFile* file, + ImageCachePerThreadInfo* thread_info, + int subimage, int miplevel, + ustring dataname, TypeDesc& datatype); + /// Get the ImageSpec associated with the named image. If the file /// is found and is an image format that can be read, store a copy /// of its specification in spec and return true. Return false if diff --git a/src/libtexture/texture_pvt.h b/src/libtexture/texture_pvt.h index a480149b54..be9e4e6eb8 100644 --- a/src/libtexture/texture_pvt.h +++ b/src/libtexture/texture_pvt.h @@ -314,6 +314,12 @@ class TextureSystemImpl final : public TextureSystem { ustring dataname, TypeDesc datatype, void* data); + virtual bool get_texture_info_type(ustring filename, int subimage, + ustring dataname, TypeDesc& datatype); + virtual bool get_texture_info_type(TextureHandle* texture_handle, + Perthread* thread_info, int subimage, + ustring dataname, TypeDesc& datatype); + virtual bool get_imagespec(ustring filename, int subimage, ImageSpec& spec); virtual bool get_imagespec(TextureHandle* texture_handle, Perthread* thread_info, int subimage, diff --git a/src/libtexture/texturesys.cpp b/src/libtexture/texturesys.cpp index 20a6d99ed8..f1577d8baa 100644 --- a/src/libtexture/texturesys.cpp +++ b/src/libtexture/texturesys.cpp @@ -567,6 +567,35 @@ TextureSystemImpl::get_texture_info(TextureHandle* texture_handle, } +bool +TextureSystemImpl::get_texture_info_type(ustring filename, int subimage, + ustring dataname, TypeDesc& datatype) +{ + bool ok = m_imagecache->get_image_info_type(filename, subimage, 0, dataname, + datatype); + if (!ok) { + std::string err = m_imagecache->geterror(); + if (!err.empty()) + error("{}", err); + } + return ok; +} +bool +TextureSystemImpl::get_texture_info_type(TextureHandle* texture_handle, + Perthread* thread_info, int subimage, + ustring dataname, TypeDesc& datatype) +{ + // This lets us ask for the datatype of a specific attribute + bool ok = m_imagecache->get_image_info_type( + (ImageCache::ImageHandle*)texture_handle, + (ImageCache::Perthread*)thread_info, subimage, 0, dataname, datatype); + if (!ok) { + std::string err = m_imagecache->geterror(); + if (!err.empty()) + error("{}", err); + } + return ok; +} bool TextureSystemImpl::get_imagespec(ustring filename, int subimage,