27th October 2009
Münster, Germany
Dirk Feldmann
dirk.feldmann at uni-muenster.de

# .flow file format

## Abstract

In order to keep track of meta-data about a dataset containing flow data, the .flow file format has been introduced for the Flowreen module within Voreen.
.flow files consist basically of raw flow data stored as little endian single precision floating point values (floats) and an additional header. This document describes the structure of those files and how to read and write them.

## File Format description

The stored data are usually linearized 2D or 3D arrays of floats. The dimension is denoted within the header. The files are (currently) designed to only contain floats and a single timestep of the flow, if it is not stationary and time-dependent.
If the flow data already exist in a .raw file, it is sufficient to add a header in order to make them accessible in the Voreen engine.
The structure of a .flow file in version 2 (current version on creation of this document) is as follows:

file header (37 bytes)
file content (n bytes of raw data)

The structure of the header for file version 2 in detail is as follows:

start offset (byte) | 0 (0x00) | 11 (0x0B) | 15 (0x0E) | 19 (0x13) | 20 (0x14) | 21 (0x15) | 25 (0x19) | 29 (0x1C) | 33 (0x21)
purpose | magic number | file version | dimensions of flow | array linearization order | slice reversal | extent in x-direction | extent in y-direction | extent in z-direction | data size (in bytes)
size (in bytes) | 11 | 4 | 4 | 1 | 1 | 4 | 4 | 4 | 4
data type (C/C++) | string (zero-terminated char array) | int | unsigned int | char | char | unsinged int | unsigned int | unsigned int | unsinged int
valid values | zero-terminated string "VOREENFLOW\0" (without quotation marks) | 2 | currently {1, 2, 3} | 0 - 5 (explanation see below) | char {'x' | 'y' | 'z' | '\0'} or numerical value {0x78, 0x79, 0x7A, 0x00} | unsigned int value > 0 | unsigned int value > 0 | unsigned int value > 0 | unsinged int value > 0

An example of a valid header in little endian byte order would be (HEX values, char values in brackets)

magic number | file version | dimensions of flow | array linearization order | slice reversal | extent in x-direction | extent in y-direction | extent in z-direction | data size in bytes
56 4F 52 45 45 4E 46 4C 4F 57 00 (VOREENFLOW\0) | 02 00 00 00 | 03 00 00 00 | 01 | 78 (z) | 80 00 00 00 | 80 00 00 00 | 20 00 00 00 | 00 00 20 00

The described three-dimensional flow has a bounding box of 128x128x32 (X x Y x Z), the 3D array is linearized in XZY order (see below) and the order of the z-slices would be reversed when the file is loaded. The size of the data results from the size of the bounding volume times the size of one float (usually 4 bytes on x86 machines): 128 x 128 x 32 x 4 = 2097152 = 0x200000 bytes.

## Details on Header Fields

### magic number |
description | The magic number identifies the file format. It must be excatly of the value described above.
### file version |
description | Indicates the version of this file to assist the file reader. File version 2 is the latest one. In file version 1, the header field slice reversal was missing.
### dimensions of flow |
description | Indicates the number of dimensions of the flow data. This value is usually 3, maybe 2. Note that the current version of the flow file reader in Voreen can only deal with 3D flows! This field has been primarily introduced for future extensions.
### array linearization order |
description | Indicates in what order the formerly 3D array has been linearized. There are six possibilities for linearization a 3D array: XYZ (code 1) XZY (code 0) YXZ (code 2) YZX (code 3) ZXY (code 4) ZYX (code 5) For instance, code 0 (XZY) means, that the former volumetric data were conceptually slices in the XZ plane whereas the x-axis is the first and the z-axis the second one, and that the slices where stacked in positive z-direction. Note: there is currently no case covering the linearization of 2D arrays for 2D flows! Note: the codes for XYZ and XZY are "e;swapped"e; for historical reasons :).
### slice reversal |
description | It may be useful or necessary to reverse the conceptual slices along a certain direction of an 3D array. This can be achieved by setting the concerned axis in the slice reversal field. For instance, if the orignal array was in order of XYZ, the xy-slices will be reversed on loading the volume into Voreen if the slice reversal field is set to 'z'. Any other of the allowed values is possible, too, depending on the actual data. Slice reversal will be omitted if the field contains the NULL-charactor (0x00). Note: currently only the slice along one axis can be reversed, for it is sufficient in many cases.
### extent in {x|y|z}-direction |
description | Indicates the extension of the volume's bounding box in x-, y- and z-direction. This is usually the number of elements in the 3D array.
### data size |
description | Indicates the size of the pending raw data in bytes. For the data are considered to be single precesion floats, the number of bytes is usually the size of one float times number the elements of the data array. This number is intended to be use for integrity checks and detection of corrupt files. Furthermore, a .flow file reader then knows how many bytes should be left for reading.