DD::Image::Interest Class Reference

Inherits DD::Image::Box.

Inherited by DD::Image::RowCacheTile.

Public Types

typedef const float * RowPtr
 type of actual row data. to be replaced with a strided pointer
typedef RowPtr const * LinePointers
 type of the linebuffer returned by operator[].
- Public Types inherited from DD::Image::Box
typedef iterator const_iterator

Public Member Functions

 Interest (Iop &, ChannelMask, bool mt=false, InterestRatchet *ir=nullptr, float fracCPU=1.0f)
 Interest (Iop &, int x, int y, int r, int t, ChannelMask, bool mt=false, InterestRatchet *ir=nullptr, float fracCPU=1.0f)
 Interest (Iop &, const Box &box, ChannelMask, bool mt=false, InterestRatchet *ir=nullptr, float fracCPU=1.0f)
 Interest (const Interest &)=delete
Interestoperator= (const Interest &)=delete
ChannelMask channels () const
void unlock ()
bool unlocked () const
bool valid () const
bool done (int y) const
bool have_memory (Channel z, int y) const
LinePointers operator[] (Channel z) const
bool is_zero (Channel z, int y) const
void load_range (int, int)
Cache * cache () const
void at (int x, int y, ChannelMask m, float *o)
float at (int x, int y, Channel z)
 ~Interest ()
- Public Member Functions inherited from DD::Image::Box
iterator begin () const
iterator end () const
 Box (int x, int y, int r, int t)
 Box (const Box &b)
int x () const
void x (int v)
int y () const
void y (int v)
int r () const
void r (int v)
int t () const
void t (int v)
int w () const
void w (int v)
int h () const
void h (int v)
float center_x () const
float center_y () const
void set (int x, int y, int r, int t)
void set (const Box &b)
bool is_constant () const
void clear ()
void move (int dx, int dy)
void pad (int dx, int dy, int dr, int dt)
void pad (int dx, int dy)
void pad (int d)
int clampx (int x) const
int clampy (int y) const
void merge (const Box &)
void merge (int x, int y)
void merge (int x, int y, int r, int t)
void expand (int amount)
void expand (int widthAmount, int heightAmount)
void scale (float scaleAmount)
void intersect (const Box &)
void intersect (int x, int y, int r, int t)
bool intersects (const Box &other) const
bool intersects (int x, int y, int r, int t) const
bool contains (const Box &other) const
int area () const

Static Public Member Functions

static IopinputIop (Iop &iop)

Protected Member Functions

void reserve_range (int bottom, int top)


class Cache
std::ostream & operator<< (std::ostream &, const Interest &)

Detailed Description

An Interest object creates a cache on the Iop and prevents any lines that are put into that cache from being deleted until the Interest is destroyed. This can be used by an engine() implementation to indicate that it will ask for the same data using Iop::at() or Iop::get() multiple times.

The lines will probably stay around for some time after the interest is destroyed, so you can assume they are still there the next time the engine() is called.

Constructor & Destructor Documentation

Interest::Interest ( Iop iop,
ChannelMask  channels,
bool  mt = false,
InterestRatchet ir = nullptr,
float  fracCPU = 1.0f 

This constructor locks the entire requested() area and all requested channels into the memory.

References inputIop(), and DD::Image::Iop::requestedBox().

Interest::Interest ( Iop iop,
int  x,
int  y,
int  r,
int  t,
ChannelMask  channels,
bool  mt = false,
InterestRatchet ir = nullptr,
float  fracCPU = 1.0f 

This constructor takes a box and channel mask, and only the interesection of these and the "requested" box and channels of the operator are locked into memory.

If channels is empty (== Mask_None) then the bounding box is not clipped.

If mt is true, threads()-1 parallel threads are started to try to fill in the lines in the interest. This should be useful for getting the input of an operator that has to run single-threaded.

References inputIop(), DD::Image::Box::intersect(), DD::Image::Box::r(), DD::Image::Iop::requestedBox(), DD::Image::Box::x(), and DD::Image::Box::y().

Interest::~Interest ( )

The destuctor unlocks the pixels from the input iop's cache.

References DD::Image::Thread::wait().

Member Function Documentation

void Interest::unlock ( )

Call this to indicate that the Interest does not actually lock lines into memory. This means the Interest is simply used to encourage caching of the lines. Calling this after calling the multithreaded constructor is an easy way to get parallel threads to generate lines you may use.

Warning: none of the access functions such as at() will work reliably after this, as the memory may disappear right in the middle of their operation! Use get() on the Iop instead to retrieve the data, or create other temporary Interests.

bool DD::Image::Interest::unlocked ( ) const

Returns true if unlock() had been called.

bool Interest::valid ( ) const

Return true if any done() data in the cache matches the current state of the Iop. Most users of Interest and Tiles do not need to check this, as the Interest is created after the Iop is validated and is destroyed before it is invalidated. You need this in case you are keeping interests around while changing the Iop data.

Referenced by DD::Image::GeneralTile::load_range(), and DD::Image::GeneralTile::valid().

bool Interest::done ( int  y) const

Returns true if line y has been calculated and thus is holding correct data in the cache memory. This means that at() will return quickly, and that operator[] will work for this line.

This is an extremely fast inline function, and it assumes y is inside the y() through t()-1 range. If y is outside this range unpredictable results occur. You can use cache->clamp(y) to move an arbitrary number in range. This also does not check valid(), if valid() is false then this may return true even if it is not.

References DD::Image::Box::y().

bool DD::Image::Interest::have_memory ( Channel  z,
int  y 
) const

Returns true if there is memory allocated for channel z of line y. If this returns true them operator[] will not crash for this channel and line. If z is one of the channels() then you can also assume that memory exists for all the other channels for this row.

The memory may contain correct data, or it may contain an older version of the image. If it contains the older version it may get overwritten with the new data at any time.

LinePointers DD::Image::Interest::operator[] ( Channel  z) const

To access an arbitrary pixel at channel z, row y, horizontal position x, call tile[z][y][x].

If you access non-existent data you will get a crash or garbage. To avoid this you must make sure that:

  1. !z || tile.channels() & z
  2. y >= tile.y() && y < tile.t()
  3. x >= tile.x() && x < tile.r()
  4. Make sure the line is done() (or at least have_memory()). For the Tile subclass you can assume this is true.

Depending on your algorithim you can usually insure this without doing a test on every pixel like at() does.

bool Interest::is_zero ( Channel  z,
int  y 
) const

Return true if it knows that this row and channel are zero. This will happen if some earlier operator called erase() on the Row when creating the data. Also the caching sometimes detects zero and turns this on.

This also returns true if the channel is not in this tile.

y is clamped to the range of the tile. However you must make sure done(y) is true (for Tile this can be assumed).

References DD::Image::Box::clampy().

Referenced by DD::Image::GeneralTile::is_zero().

void Interest::load_range ( int  bottom,
int  top 

Load a set of lines, so that done() is true for all lines from bottom to top-1. Obeys the ydirection and cooperates with other threads that may be loading the same set of lines. The range must line inside the y() to t()-1 range of the Interest or unpredicable results will occur!

For historical reasons setting the cache pointer to null is used to signal the threads to quit. The destructor for the Interest does this and then waits for this function to return.

Referenced by DD::Image::GeneralTile::load_range().

void Interest::at ( int  x,
int  y,
ChannelMask  m,
float *  o 

Return several channels of a pixel in the interest. The passed array is indexed by channel number and filled in with the values from the image. Unrequested channels (including Chan_Black) are unchanged in the array. The array must be big enough to contain the largest of the requested channels.

If a channel was not asked for in the constructor or was not in the requested_channels() of the iop then zero is returned.

The x and y coordinates are moved to the nearest edge of the interest's area, which is the intersection of the requested() area of the iop and the arguments passed to the constructor.

Conceivably this is faster than Iop::at() because it can assume the lines are already locked, but currently it is the same speed.

References DD::Image::Box::clampx(), and DD::Image::Box::clampy().

float Interest::at ( int  x,
int  y,
Channel  z 

Return a single channel of a pixel in the interest.

If the channel was not asked for or was not in the requested_channels() of the iop then zero is returned.

The x and y coordinates are moved to the nearest edge of the interest area, which is the intersection of the requested() area of the iop and the arguments passed to the constructor.

Because the interest guarantees that a line stays in memory, this will probably be faster than Iop::at() for the second and subsequent requests for pixels in the same row.

References DD::Image::Box::clampx(), DD::Image::Box::clampy(), and DD::Image::Box::y().

Iop * Interest::inputIop ( Iop iop)

the topmost op that actually contributes image data into /iop/

References DD::Image::Iop::input(), and DD::Image::Iop::out_channels().

Referenced by DD::Image::GeneralTile::getRequestBox(), and Interest().

void Interest::reserve_range ( int  bottom,
int  top 

Declares an interest in the specified range of scanlines without actually loading them into the cache. Used for on-demand loading of tiles

Friends And Related Function Documentation

std::ostream& operator<< ( std::ostream &  ,
const Interest  

Not implemented in the library but you can define it.

©2022 The Foundry Visionmongers, Ltd. All Rights Reserved.