int get_restriction(int *iXll, int *iYll, int *iWidth, int *iHeight, int *piField, unitptr uHost)(The return value of this routine is 1, if restriction information could be retrieved, zero else. In the second case, the argument parameters are unchanged) This mechanism can be used to optimize the implementation of pixel-manipulating NST-units. To this end, before attempting its operations, a unit should get the restriction information currently associated with its packed input field(s) and then restrict all pixel manipulations to the restriction area only. In addition, if a unit computes values for a packed output field, it can on each execution call set a restriction area in that output field that bounds only the subset of pixel values that were changed due to the current call of the unit. Units that implement such a `Autorestriction''-scheme will thus automatically pass the effect of any restrictions on their inputs to their outputs and thereby allow to constrain the processing of their successors to a dynamically changeable subregion of an image. This scheme is particularly valuable, when only a single pixel changes, or no pixel at all. A third possibility for optimization is that a unit uses restrictions associated with its output field(s) to carry out only those computations that can affect values in the restriction area(s) of its packed output field(s). For instance, a frame-grabber unit might bound the image pixels that have changed in a subrectangle, thus restricting the processing of subsequent units to the changed region only. Similarly, in a pipeline of units each of which performs some local filtering information on its input and copies the result to its output, a restriction to a subrectangle at the input can propagete through the entire pipeline, restricting the filtering operations of each member in the pipeline to the restriction area at the input of the pipeline (or, if the filtering operation of a unit is a convolution with a kernel of size 2m+1, the filtering unit will pass a restriction area with an edge size enlarged by 2m to its successor). Whether and to which extent a unit uses this mechanism should be explained in its documentation. As a general rule, if pixels of an image have changed only in a subrectangle, then using this subrectangle as restriction area should not affect the results computed by a unit, only the execution time. If a new connection between two packed fields is formed, the restriction area of the source field (the writer) is set to the smallest rectangle containing the previous restriction areas of both fields (technically, this is achieved by a call of set_restriction for the destination field, but after the connection is established). If a connection is separated, the restriction areas associated with the separated fields remain unchanged. If a field is read by multiple readers, its restriction area must contain the restriction areas of all readers. Therefore, a single reader that always requests the entire image will spoil any possibilies for work reduction, even if all other readers request only tiny image portions. Therefore, it may be useful to implement some readers in such a way that they follow with their restriction area any more modest request. This is achieved when the last statement in a readers exec-routine is a set_restriction with zero height and width, and the first statement a get_restriction of its input field. For instance, the write_pix - units are implemented in this way.
set_field_rectangular(int iDx, int iDy, field* pField, unitptr pHost)For an uninitialized field, the restriction area will be always fullsize [this is a safeguard against forgotten initializations]. b) To optimize the implementation of a unit in the simplest case (local filtering), restrict the usual processing loop
for (i=0; i<iDx*iDy; i++) / * process value XP(uUnit,f,i) * /for a pixel array of size iDx*iDy to the subset of indices belonging to pixels in the restriction area. This requires
get_restriction(&iXll,&iYll,&iWidth,&iHeight,piField,uUnit); iStart = iYll*iDx + iXll; iEnd = iStart + (iHeight-1)*iDx + iWidth -1; for (iXStart=iStart; iXStart<iEnd; iXStart += iDx) for (i = iXStart; i<iXStart+iWidth; i++) / * process value XP(u,f,i) * /For a newly created packed field, the default values are iXll=iYll=0, iHeight=1, iWidth=iDx*iDy. This will ensure that iStart=0 and iEnd=iDx*iDy, i.e., processing will extend across the entire image region.