The concept of blocking is similar to chunking, except that it is appropriate when the relative positions of pixels within an NDF are significant. In one dimension, chunking and blocking are equivalent, so a 2-dimensional example is required for illustration.
Suppose that a contour map of a very large 2-dimensional image is to be generated, and that the image must be divided into pieces to limit memory usage. Chunking would not be appropriate here, because (depending on its shape) a chunk might work out to be a single line of the image, and this would result in inefficient contouring. Rather than setting an upper limit on the total size of each piece, what we need to limit here is the size of each dimension. This means that we must ``tile'' the 2-dimensional image with a series of adjacent rectangular regions, each of which does not exceed a certain size in each dimension, and each of which can be contoured in turn. This form of partitioning is what blocking provides, the ``tiles'' (in N dimensions) being termed blocks.
Blocking is supported by two routines analogous to those provided for chunking. NDF_NBLOC calculates the number of blocks available in an NDF (for given limits on the dimension sizes), while NDF_BLOCK creates the NDF sections which refer to the individual blocks, each of which is identified by a block index. The following illustrates the principle:
INTEGER IBLOCK, IBL, MXDIM( 2 ), NBLOCK
DATA MXDIM / 100, 100 /
...
* Determine the number of blocks available.
CALL NDF_NBLOC( INDF, 2, MXDIM, NBLOCK, STATUS )
* Loop through the blocks, creating a section to refer to each one.
DO 1 IBLOCK = 1, NBLOCK
CALL NDF_BLOCK( INDF, 2, MXDIM, IBLOCK, IBL, STATUS )
<contour the resulting section/block>
* Annul the section identifier.
CALL NDF_ANNUL( IBL, STATUS )
1 CONTINUE
In this 2-dimensional example, each block is constrained so as not to exceed 100 pixels in size in each dimension, these limits being specified in the MXDIM array.
Note that blocking generates sections which lie adjacent to one another, rather than being contiguously stored, as is the case with chunking. Blocks are numbered so that their lower/upper bounds increase in the conventional sense with increasing block index (i.e. with the first dimension bound increasing most rapidly and the last bound increasing least rapidly). As with chunking, the size of each block generated by NDF_BLOCK may vary in order to lie within the original NDF (using the ``tiling'' analogy, there may be some tiles at the edges which must be ``cut'' to fit), but the sequence of blocks generated is always repeatable.
By supplying special values to NDF_BLOCK for the MXDIM value of each dimension, it is also possible to step through an NDF in blocks of a pre-determined shape (as with chunking). For instance, if the integer array DIM holds the original NDF dimensions, then the assignment:
MXDIM( 1 ) = DIM( 1 )
could be used to step through an image in ``lines'', while the assignment:
MXDIM( 1 ) = DIM( 1 )
MXDIM( 2 ) = DIM( 2 )
would step through a 3-dimensional image stack in ``planes''. The assignment:
MXDIM( 1 ) = 1
MXDIM( 2 ) = DIM( 2 )
could also be used to step through an image in ``columns'', but note that this non-sequential mode of access may not be efficient.