ImFusion SDK 4.3
SharedImage Class Reference

#include <ImFusion/GL/SharedImage.h>

Image shared on multiple devices. More...

Detailed Description

Image shared on multiple devices.

This class aids in resource synchronization between CPU and different GPU APIs. It is constructed with a derived image instance either in memory or one of the graphics APIs, an empty base descriptor class is not allowed. In addition to the built-in representations such as MemImage and GlImage it also supports custom representations provided by plugins through the CustomImage interface.

Internally, for each image representation, a shared pointer is held. Synchronization is fully encapsulated and will be performed even on const instances of this class because mere synchronization between devices does not modify the semantic content of an image.

For individual image access, adhere to the following guidelines:

  1. Use descriptor() or img() to obtain a const image descriptor regardless of the image location.
  2. Use sharedMem(), sharedGl(), and sharedCustom<T>() for getting a shared_ptr to the respective image. If the desired representation is absent or outdated, it will be synchronized, even if the method is called on a const object. Thus, make sure to call these methods only if synchronization is allowed, for instance with a valid GL context when calling sharedGl().
  3. The same holds for methods mem(), gl(), and custom<T>(), which return non-owning raw pointers held by sharedMem(), sharedGl(), and sharedCustom<T>() respectively.
  4. Use hasMem(), hasGl(), hasCustom<T>() to check for an up-to-date representation while making sure that no synchronization is performed. The returned shared_ptr implicitly casts to bool. Furthermore, it allows for working and to work with the potentially available representation in a thread-safe way. If you use SharedImage in a multi-threaded environment, do not: if (img.hasGl()) { auto gl = img.gl(); // wrong, could have been overridden in other thread since hasGl() ... } but instead: if (auto gl = img.hasGl()) { // correct, guaranteed to return either valid image or nullptr ... }
  5. If you change the image in one representation, e.g. in memory, make sure to call setDirtyMem(), setDirtyGl(), setDirtyCustom<T>(), so that all other representations are marked as outdated.
  6. Explicitly call makeExclusive() to remove all representations except one from this container. This might be useful for memory management, e.g. to free GL textures.
Warning
By definition a GlImage can not store more than 4 channels (this is a general limitation of OpenGL). SharedImage will deal with this as follows: When syncing a MemImage -> GlImage, the GL representation will only contain the first 4 channels, any extra channels will be discarded. Subsequent calls to setDirtyGl() will not have any effect but only issue a warning because the GlImage is incomplete, and you would lose data otherwise. If you nevertheless want to sync back to MemImage, you need to do this manually to acknowledge that you may lose data. You can do this for instance by using GlImage::download() to create a MemImage followed by SharedImage::assign() or SharedImage::update().
See also
Using Image Data

Classes

struct  Representation
 

Public Types

enum  CloneOptions { Everything = 0 , NoMask = 1 << 0 , NoDeformation = 1 << 1 , ShallowImageCopy = 1 << 2 }
 Bitset enumeration to configure which aspects of a SharedImageSet to copy. More...
 

Public Member Functions

 SharedImage (std::shared_ptr< Image > img)
 Creates a new SharedImage wrapping the given image.
 
template<typename T>
 SharedImage (TypedImage< T > &&img)
 Creates a new SharedImage by moving the given TypedImage in.
 
 SharedImage (GlImage &&img)
 Creates a new SharedImage by moving the given GlImage in.
 
 SharedImage (const ImageDescriptor &descriptor)
 Convenience overload to create a new SharedImage holding a MemImage as described by the ImageDescriptor.
 
 SharedImage (const ImageDescriptorWorld &descriptorWorld)
 Convenience overload to create a new SharedImage holding a MemImage as described by the ImageDescriptorWorld.
 
 SharedImage (const SharedImage &otherSharedImage)
 Copy constructor performs a deep copy of the underlying image data.
 
 SharedImage (const SharedImage &otherSharedImage, Flags< CloneOptions > copyOptions)
 Copy constructor variant that also allows for partial copies.
 
 SharedImage (SharedImage &&otherSharedImage)
 Move constructor will move all contents from otherSharedImage.
 
SharedImageoperator= (const SharedImage &otherSharedImage)
 Assignment will perform a deep copy of the underlying image data.
 
SharedImageoperator= (SharedImage &&otherSharedImage)
 Move assignment will move all contents from otherSharedImage.
 
std::unique_ptr< SharedImageclone (Flags< CloneOptions > cloneOptions=Everything) const
 More flexible version of the copy constructor that also allows for partial copies.
 
Image::Location location () const
 Specifies the original location of the image.
 
const Imageimg () const
 Return the image descriptor of the currently up-to-date location.
 
const ImageDescriptordescriptor () const
 Return the image descriptor of the currently up-to-date location.
 
ImageDescriptorWorld descriptorWorld () const
 Return the world image descriptor of the currently up-to-date location.
 
bool assign (std::shared_ptr< Image > img)
 Set img as new main image representation and set the dirty flag accordingly.
 
bool update (const MemImage &img)
 Update the MemImage and set the dirty flag so that the next OpenGL access will upload this image.
 
bool update (const GlImage &img)
 Update the GlImage and set the dirty flag so that the next CPU access will download this image.
 
void prepare (bool shiftOnly=false)
 Prepare the image in memory for most common scenarios Integral types are converted to unsigned representation if applicable, double-precision will be converted to single-precision float.
 
virtual void sync () const
 Synchronize both MemImage and GlImage representations, shorthand for calling both syncMem() and syncGl().
 
virtual void syncMem () const
 Synchronize MemImage, creating it if it does not exist.
 
template<typename T>
void syncCustom () const
 Synchronize a custom image type where T must inherit the CustomImage interface, creating it if it does not exist.
 
virtual void syncGl () const
 Synchronize OpenGL image, creating it if it does not exist.
 
void setDirtyMem ()
 Manually label MemImage as dirty (i.e.
 
bool setDirtyGl ()
 Manually label GlImage as dirty (i.e.
 
template<typename T>
void setDirtyCustom ()
 Manually label custom image type T as dirty (i.e.
 
bool makeExclusive (Image::Location location) const
 Synchronizes the given location and deletes all other representations stored to free memory.
 
template<typename T>
bool makeExclusive ()
 
Data::Kind kind () const
 Return the data kind of the base interface.
 
Geometry::AlignedBox bounds () const
 Returns the axis-aligned bounding box of the unmasked and undeformed image in world space.
 

Public Attributes

Signal< const SharedImage * > signalChanged
 Called when the content of a SharedImage has changed (every time one of the setDirty() methods has been called).
 
Signal< const SharedImage * > signalDeformationChanged
 Called when a Deformation object is assigned or removed from the SharedImage.
 
Signal< const SharedImage * > signalMaskChanged
 Called when a Mask object is assigned or removed from the SharedImage.
 
Signal< const SharedImage * > signalDeleted
 Called when this instance is deleted.
 

Protected Member Functions

void validateMask ()
 Removes invalid masks.
 
bool checkConsistency () const
 Check the internal state for consistency. May find occasions where a user forgot to call setDirty().
 

Protected Attributes

Image::Location m_location = Image::NONE
 The original location of the image.
 
Data::Modality m_modality = Data::NA
 Image modality.
 
mat4 m_matrix = mat4::Identity()
 The optional image matrix.
 
std::shared_ptr< Deformationm_deformation
 Optional non-linear transformation.
 
std::shared_ptr< Maskm_mask
 Optional mask.
 
std::shared_ptr< MemImagem_memImg
 Image in memory.
 
std::shared_ptr< GlImagem_glImg
 OpenGL texture.
 
bool m_memDirty = true
 Indicates whether m_memImg is obsolete, and needs to be refreshed on access.
 
bool m_glDirty = true
 Indicates whether m_glImg is obsolete, and needs to be refreshed on access.
 
std::vector< Representationm_customImgs
 List of custom Image representations that are not known to ImFusionLib but can be converted from/to MemImage.
 
bool m_glImgHasStrippedChannels = false
 Indicates that the GL representation was created from an image with > 4 channels.
 
Geometry::AlignedBox m_bounds
 Cached version of the axis-aligned bounding box in world space.
 
bool m_boundsDirty = true
 Flag whether m_bounds needs to be recomputed.
 

Access to direct members of SharedImage

void setModality (Data::Modality m)
 Set image modality.
 
Data::Modality modality () const
 Return the modality of this data.
 
void setMask (std::shared_ptr< Mask > mask)
 Sets a mask for this image.
 
std::shared_ptr< Maskmask () const
 Returns the mask for this image.
 
void setDeformation (std::shared_ptr< Deformation > def)
 Sets a deformation for this image.
 
std::shared_ptr< Deformationdeformation () const
 Returns the deformation for this image or nullptr if no deformation is set.
 

Query an up-to-date representation.

These functions will always perform an implicity synchronization if needed. Use hasMem() to check if synchronization is required or to obtain an already existing image without synchronization.
std::shared_ptr< MemImagesharedMem ()
 Returns the image in memory.
 
std::shared_ptr< const MemImagesharedMem () const
 
std::shared_ptr< GlImagesharedGl ()
 Returns the image as OpenGL texture.
 
std::shared_ptr< const GlImagesharedGl () const
 
template<typename T>
std::shared_ptr< T > sharedCustom ()
 Returns the image as custom image type, where T must inherit the CustomImage interface.
 
template<typename T>
std::shared_ptr< const T > sharedCustom () const
 
MemImagemem ()
 Returns the image in memory.
 
const MemImagemem () const
 
GlImagegl ()
 Returns the image as OpenGL texture.
 
const GlImagegl () const
 
template<typename T>
T * custom ()
 Returns the image as custom image type, where T must inherit the CustomImage interface.
 
template<typename T>
const T * custom () const
 

Query whether an up-to-date representation is present and return it.

If a nullptr is returned this indicates that a sync would be required. Use sharedMem() or mem() if implicit synchronization is desired. The returned shared pointer implicitly casts to bool, so you can use it as follows:
if (auto mem = img.hasMem())
...
MemImage * mem()
Returns the image in memory.
const Image * img() const
Return the image descriptor of the currently up-to-date location.
std::shared_ptr< const MemImagehasMem () const
 Query whether an up-to-date memory image is present.
 
std::shared_ptr< MemImagehasMem ()
 
std::shared_ptr< const GlImagehasGl () const
 Query whether an up-to-date OpenGL image is present.
 
std::shared_ptr< GlImagehasGl ()
 
template<typename T>
std::shared_ptr< T > hasCustom ()
 Query whether an up-to-date image of the requested type is present, where T must inherit the CustomImage interface.
 
template<typename T>
std::shared_ptr< const T > hasCustom () const
 

Image matrix access

By convention this matrix transforms world coordinates to image coordinates.

See also
Coordinate Systems
void setMatrix (const mat4 &m)
 Sets the transformation matrix from world space to image space.
 
const mat4 & matrix () const
 Returns the transformation matrix from world space to image space.
 
mat4 matrixToWorld () const
 Returns the transformation matrix from image space to world space.
 
void setMatrixToWorld (const mat4 &value)
 Sets the transformation matrix from image space to world space.
 
const mat4 & matrixFromWorld () const
 Returns the transformation matrix from world space to image space.
 
void setMatrixFromWorld (const mat4 &value)
 Sets the transformation matrix from world space to image space.
 

Convenience functions for coordinate transformations of images

vec3 pixelToWorld (const vec3 &pixel) const
 Convert a 3D pixel/voxel position to world coordinates taking into account the image matrix.
 
vec3 worldToPixel (const vec3 &world) const
 Convert 3D world coordinates to pixel/voxel position taking into account the image matrix.
 
mat4 pixelToWorldMatrix () const
 Returns a 4x4 matrix to transform from image pixel space to world space.
 
mat4 worldToPixelMatrix () const
 Returns a 4x4 matrix to transform from world space to image pixel space.
 
mat4 textureToWorldMatrix () const
 Returns a 4x4 matrix to transform from texture space to world space.
 
mat4 worldToTextureMatrix () const
 Returns a 4x4 matrix to transform from world space to texture space.
 
mat4 textureToImageMatrix () const
 Returns a 4x4 matrix to transform from texture space to image space.
 
mat4 imageToTextureMatrix () const
 Returns a 4x4 matrix to transform from image space to texture space.
 

Convenience functions to access underlying image descriptor directly

int width () const
 Return the width of the base interface.
 
int height () const
 Return the height of the base interface.
 
int slices () const
 Return the number of slices of the base interface.
 
int channels () const
 Return the number of channels of the base interface.
 
vec3 spacing () const
 Return the image spacing.
 
void setSpacing (const vec3 &spacing)
 Set the image spacing on all existing image representations.
 
void setSpacing (const vec3 &spacing, bool metric)
 Set the image spacing on all existing image representations, and whether the spacing is metric.
 
int dimension () const
 Return the image dimensions.
 
vec3i dimensions () const
 Return the image dimensions.
 
size_t size () const
 Return the image size.
 
vec3 extent () const
 Return the image extent.
 

Member Enumeration Documentation

◆ CloneOptions

Bitset enumeration to configure which aspects of a SharedImageSet to copy.

Enumerator
Everything 

Perform a deep copy of the image data and shallow copies of the mask and deformation.

NoMask 

Do not copy the attached mask.

NoDeformation 

Do not copy the attached deformation.

ShallowImageCopy 

Do not deep copy the SharedImages but only copy the shared_ptrs.

Constructor & Destructor Documentation

◆ SharedImage()

SharedImage ( std::shared_ptr< Image > img)
explicit

Creates a new SharedImage wrapping the given image.

Parameters
imgPointer to the image to initialize the SharedImage with, must not be null.
Note
You can also pass any std::unique_ptr<Image> as it implicitly converts to a std::shared_ptr of same type.

Member Function Documentation

◆ img()

const Image * img ( ) const

Return the image descriptor of the currently up-to-date location.

Deprecated
Use descriptor() instead.

◆ setMask()

void setMask ( std::shared_ptr< Mask > mask)

Sets a mask for this image.

Only masks that are compatible with the image can be set. Incompatible masks will be ignored. The signalMaskChanged signal is emitted whenever the mask pointer changes.

◆ mask()

std::shared_ptr< Mask > mask ( ) const

Returns the mask for this image.

Returns nullptr if no mask is set or the current mask is not compatible to the image anymore.

◆ assign()

bool assign ( std::shared_ptr< Image > img)

Set img as new main image representation and set the dirty flag accordingly.

This function will move/sink in the image. Use update() if you want to copy the image data instead.

◆ update() [1/2]

bool update ( const MemImage & img)

Update the MemImage and set the dirty flag so that the next OpenGL access will upload this image.

This function will copy the image data into the SharedImage. Use the assign() if you want to move/sink the image in instead.

◆ update() [2/2]

bool update ( const GlImage & img)

Update the GlImage and set the dirty flag so that the next CPU access will download this image.

This function will copy the image data into the SharedImage. Use the assign() if you want to move/sink the image in instead.

◆ prepare()

void prepare ( bool shiftOnly = false)

Prepare the image in memory for most common scenarios Integral types are converted to unsigned representation if applicable, double-precision will be converted to single-precision float.

Furthermore, if shiftOnly is false it will rescale the present intensity range to [0..1] for floating point types or to the entire available value range for integral types.

Note
Pointers to the underlying image data may be invalidated as a result.

◆ syncGl()

virtual void syncGl ( ) const
virtual

Synchronize OpenGL image, creating it if it does not exist.

Note
This method throws an exception if OpenGL texture creation fails.

◆ setDirtyMem()

void setDirtyMem ( )

Manually label MemImage as dirty (i.e.

the other representations must be updated). An implicit synchronization will happen automatically the next time another representation is requested.

◆ setDirtyGl()

bool setDirtyGl ( )

Manually label GlImage as dirty (i.e.

the other representations must be updated) An implicit synchronization will happen automatically the next time another representation is requested.

Note
This function will have no effect if the GlImage was originally created from a MemImage with more that 4 channels (cf. class documentation above).

◆ setDirtyCustom()

template<typename T>
void setDirtyCustom ( )

Manually label custom image type T as dirty (i.e.

the other representations must be updated) An implicit synchronization will happen automatically the next time another representation is requested.

◆ makeExclusive()

bool makeExclusive ( Image::Location location) const

Synchronizes the given location and deletes all other representations stored to free memory.

Returns
True if successful.
Note
This function is only implemented for the locations MEMORY, OPENGL.

Member Data Documentation

◆ signalChanged

Signal<const SharedImage*> signalChanged

Called when the content of a SharedImage has changed (every time one of the setDirty() methods has been called).

Note
This method may be called frequently during the processing of algorithms. When connecting to this signal, make absolutely sure to not include any expensive operations! Otherwise you may introduce a performance hit to the entire application. All you should do is setting a dirty flag yourself if needed.

◆ signalMaskChanged

Signal<const SharedImage*> signalMaskChanged

Called when a Mask object is assigned or removed from the SharedImage.

Note
Listeners are not immediately notified when a mask becomes incompatible with the image, but only after the first call to SharedImage::mask().

◆ signalDeleted

Signal<const SharedImage*> signalDeleted

Called when this instance is deleted.

Warning
Use with caution, only pointer comparison is allowed! This method is called from a SharedImage instance in the destructor of the very base class, therefore no type information for dynamic casts or other class attributes are available anymore.

◆ m_glImgHasStrippedChannels

bool m_glImgHasStrippedChannels = false
mutableprotected

Indicates that the GL representation was created from an image with > 4 channels.

Since OpenGL does not support this the GL representation only stores the first 4 channels. A subsequent call to setDirtyGl() has no effect to avoid data loss.


The documentation for this class was generated from the following file:
Search Tab / S to search, Esc to close