Next: Tile grid, Previous: Tessellation library, Up: Tessellation library [Contents][Index]
The most general application of tiles is to treat each independently, for example they may overlap, or they may not cover the full image. This section provides functions to help in checking/inspecting such tiles. In Tile grid we will discuss functions that define/work-with a tile grid (where the tiles don’t overlap and fully cover the input dataset). Therefore, the functions in this section are general and can be used for the tiles produced by that section also.
*tile
, size_t *start_coord
)Calculate the starting coordinates of a tile in its allocated block of
memory and write them in the memory that start_coord
points to
(which must have tile->ndim
elements).
*tile
, size_t *start_end
, int rel_block
)Put the starting and ending (end point is not inclusive) coordinates of
tile
into the start_end
array. It is assumed that a space of
2*tile->ndim
has been already allocated (static or dynamic) for
start_end
before this function is called.
rel_block
(or relative-to-block) is only relevant when tile
has an intermediate tile between it and the allocated space (like a
channel, see gal_tile_full_two_layers
). If it doesn’t
(tile->block
points the allocated dataset), then the value to
rel_block
is irrelevant.
When tile->block
is its self a larger block and rel_block
is
set to 0, then the starting and ending positions will be based on the
position within tile->block
, not the allocated space.
*tile
, gal_data_t *work
, size_t *start_end_inc
)Put the indexs of the first/start and last/end pixels (inclusive) in a tile
into the start_end
array (that must have two elements). NOTE: this
function stores the index of each point, not its coordinates. It will then
return the pointer to the start of the tile in the work
data
structure (which doesn’t have to be equal to tile->block
.
The outputs of this function are defined to make it easy to parse over an
n-dimensional tile. For example, this function is one of the most important
parts of the internal processing of in GAL_TILE_PARSE_OPERATE
function-like macro that is described below.
*block
, size_t *minmax
, size_t number
)Construct a list of tile(s) given coordinates of the minimum and maximum of
each tile. The minimum and maximums are assumed to be inclusive and in C
order (slowest dimension first). The returned pointer is an allocated
gal_data_t
array that can later be freed with
gal_data_array_free
(see Arrays of datasets). Internally, each
element of the output array points to the next element, so the output may
also be treated as a list of datasets (see List of gal_data_t
) and
passed onto the other functions described in this section.
The array keeping the minimum and maximum coordinates for each tile must
have the following format. So in total minmax
must have
2*ndim*number
elements.
| min0_d0 | min0_d1 | max0_d0 | max0_d1 | ... ... | minN_d0 | minN_d1 | maxN_d0 | maxN_d1 |
*tile
)Return the dataset that contains tile
’s allocated block of
memory. If tile is immediately defined as part of the allocated block, then
this is equivalent to tile->block
. However, it is possible to have
multiple layers of tiles (where tile->block
is itself a tile). So
this function is the most generic way to get to the actual allocated
dataset.
*block
, size_t *tsize
, size_t num_increment
, size_t *coord
)Return the increment necessary to start at the next contiguous patch memory
associated with a tile. block
is the allocated block of memory and
tsize
is the size of the tile along every dimension. If coord
is NULL
, it is ignored. Otherwise, it will contain the coordinate of
the start of the next contiguous patch of memory.
This function is intended to be used in a loop and num_increment
is
the main variable to this function. For the first time you call this
function, it should be 1
. In subsequent calls (while you are parsing
a tile), it should be increased by one.
*tilevalues
, gal_data_t *tilesll
, int withblank
, int initialize
)Write a constant value for each tile over the area it covers in an
allocated dataset that is the size of tile
’s allocated block of
memory (found through gal_tile_block
described above). The arguments
to this function are:
tilevalues
This must be an array that has the same number of elements as the nodes in
in tilesll
and in the same order that ‘tilesll’ elements are parsed
(from top to bottom, see Linked lists (list.h)). As a result the array’s
number of dimensions is irrelevant, it will be parsed contiguously.
tilesll
The list of input tiles (see List of gal_data_t
). Internally, it
might be stored as an array (for example the output of
gal_tile_series_from_minmax
described above), but this function
doesn’t care, it will parse the next
elements to go to the next
tile. This function will not pop-from or free the tilesll
, it will
only parse it from start to end.
withblank
If the block containing the tiles has blank elements, those blank elements will be blank in the output of this function also, hence the array will be initialized with blank values when this option is called (see below).
initialize
Initialize the allocated space with blank values before writing in the constant values. This can be useful when the tiles don’t cover the full allocated block.
*tilesll
)Make a copy of the memory block and fill it with the index of each tile in
tilesll
(counting from 0). The non-filled areas will have blank
values. The output dataset will have a type of GAL_TYPE_INT32
(see
Library data types (type.h)).
This function can be used when you want to check the coverage of each tile
over the allocated block of memory. It is just a wrapper over the
gal_tile_block_write_const_value
(with withblank
set to zero).
*tile
, gal_data_t *other
)Return the pointer corresponding to the start of the region covered by
tile
over the other
dataset. See the examples in
GAL_TILE_PARSE_OPERATE
for some example applications of this
function.
*tilell
, size_t numthreads
)Check if each tile in the list has blank values and update its flag
to mark this check and its result (see Generic data container (gal_data_t
)). The
operation will be done on numthreads
threads.
IN
, OTHER
, PARSE_OTHER
, CHECK_BLANK
, OP
)Parse IN
(which can be a tile or a fully allocated block of memory)
and do the OP
operation on it. OP
can be any combination of C
expressions. If OTHER!=NULL
, OTHER
will be interpreted as a
dataset and this macro will allow access to its element(s) and it can
optionally be parsed while parsing over IN
.
If OTHER
is a fully allocated block of memory (not a tile), then the
same region that is covered by IN
within its own block will be
parsed (the same starting pixel with the same number of pixels in each
dimension). Hence, in this case, the blocks of OTHER
and IN
must have the same size. When OTHER
is a tile it must have the same
size as IN
and parsing will start from its starting element/pixel.
Also, the respective allocated blocks of OTHER
and IN
(if
different) may have different sizes. Using OTHER
(along with
PARSE_OTHER
), this function-like macro will thus enable you to parse
and define your own operation on two fixed size regions in one or two
blocks of memory. In the latter case, they may have different numeric
data types, see Numeric data types).
The input arguments to this macro are explained below, the expected type of each argument are also written following the argument name:
IN (gal_data_t)
Input dataset, this can be a tile or an allocated block of memory.
OTHER (gal_data_t)
Dataset (gal_data_t
) to parse along with IN
. It can be
NULL
. In that case, o
(see description of OP
below)
will be NULL
and should not be used. If PARSE_OTHER
is zero,
only its first element will be used and the size of this dataset is
irrelevant.
When OTHER
is a block of memory, it has to have the same size as the
allocated block of IN
. When its a tile, it has to have the same size
as IN
.
PARSE_OTHER (int)
Parse the other dataset along with the input. When this is non-zero and
OTHER!=NULL
, then the o
pointer will be incremented to cover
the OTHER
tile at the same rate as i
, see description of
OP
for i
and o
.
CHECK_BLANK (int)
If it is non-zero, then the input will be checked for blank values and
OP
will only be called when we are not on a blank element.
OP
Operator: this can be any number of C expressions. This macro is going to
define a itype *i
variable which will increment over each element of
the input array/tile. itype
will be replaced with the C type that
corresponds to the type of INPUT
. As an example, if INPUT
’s
type is GAL_DATA_UINT16
or GAL_DATA_FLOAT32
, i
will be
defined as uint16
or float
respectively.
This function-like macro will also define an otype *o
which you can
use to access an element of the OTHER
dataset (if
OTHER!=NULL
). o
will correspond to the type of OTHER
(similar to itype
and INPUT
discussed above). If
PARSE_OTHER
is non-zero, then o
will also be incremented to
the same index element but in the other array. You can use these along with
any other variable you define before this macro to process the input and/or
the other.
All variables within this function-like macro begin with tpo_
except
for the three variables listed below. Therefore, as long as you don’t start
the names of your variables with this prefix everything will be fine. Note
that i
(and possibly o
) will be incremented once by this
function-like macro, so don’t increment them within OP
.
i
Pointer to the element of INPUT
that is being parsed with the proper
type.
o
Pointer to the element of OTHER
that is being parsed with the proper
type. o
can only be used if OTHER!=NULL
and it will be
parsed/incremented if PARSE_OTHER
is non-zero.
b
Blank value in the type of INPUT
.
You can use a given tile (tile
on a dataset that it was not
initialized with but has the same size, let’s call it new
) with the
following steps:
void *tarray; gal_data_t *tblock; /* `tile->block' must be corrected AFTER `tile->array'. */ tarray = tile->array; tblock = tile->block; tile->array = gal_tile_block_relative_to_other(tile, new); tile->block = new; /* Parse and operate over this region of the `new' dataset. */ GAL_TILE_PARSE_OPERATE(tile, NULL, 0, 0, { YOUR_PROCESSING; }); /* Reset `tile->block' and `tile->array'. */ tile->array=tarray; tile->block=tblock;
You can work on the same region of another block in one run of this
function-like macro. To do that, you can make a fake tile and pass that as
the OTHER
argument. Below is a demonstration, tile
is the
actual tile that you start with and new
is the other block of
allocated memory.
size_t zero=0; gal_data_t *faketile; /* Allocate the fake tile, these can be done outside a loop * (over many tiles). */ faketile=gal_data_alloc(NULL, new->type, 1, &zero, NULL, 0, -1, 1, NULL, NULL, NULL); free(faketile->array); /* To keep things clean. */ free(faketile->dsize); /* To keep things clean. */ faketile->block = new; faketile->ndim = new->ndim; /* These can be done in a loop (over many tiles). */ faketile->size = tile->size; faketile->dsize = tile->dsize; faketile->array = gal_tile_block_relative_to_other(tile, new); /* Do your processing.... in a loop (over many tiles). */ GAL_TILE_PARSE_OPERATE(tile, faketile, 1, 1, { YOUR_PROCESSING_EXPRESSIONS; }); /* Clean up (outside the loop). */ faketile->array=NULL; faketile->dsize=NULL; gal_data_free(faketile);
Next: Tile grid, Previous: Tessellation library, Up: Tessellation library [Contents][Index]
GNU Astronomy Utilities 0.13 manual, September 2020.