Get Teem at SourceForge.net. Fast, secure and Free Open Source software downloads
teem / nrrd

  NRRD-Compatible File Formats

The nrrd library knows how to read NRRD files, as well as three other formats of data: plain text files, PGM/PPM images, and PNG images. There is also limited support for the VTK file format. This page describes how the nrrd library interprets and uses these formats.

Reading and Writing non-NRRD files

NRRD-compatible files are read with the same nrrdRead() and nrrdLoad() functions as used for NRRD files. The type of the file is detected by nrrdRead(), which then calls the appropriate format-specific reader. There is currently no way to learn or store the format of a file once the reading is finished.

NRRD-compatible files are written with the same nrrdWrite() and nrrdSave() functions as used for NRRD files. nrrdWrite() relies on the NrrdIO struct for IO-specific state, and will write the data in whatever format is indicated by the format field of the NrrdIO. nrrdSave() also uses the NrrdIO in this capacity, but if a NrrdIO was not given, or if it does not specify a format, then nrrdSave() will try guess the format based on the given filename. Currently, this functionality is implemented by _nrrdGuessFormat(), and works according to the following table. The filename extension (1st column) determines the format (2nd column), but subject to the constraints on the Nrrd struct containing the array (3rd column) and the requested encoding (4rth column).

If the constraints are not met (as determined by nrrdFitsInFormat), the Nrrd is saved in NRRD format, using the given (and thereby misleading) filename. A warning message is printed telling that the implied requested format won't be used.

extension (case sensitive) format (nrrdFormat* enum value) Nrrd constraint encoding constraint
".txt" plain text file (nrrdFormatTable) dimensions must be 1 or 2; type can be anything except block. On reading, the dimension will be 2 (except if "# dimension: 1" appears before the data), and type will be float encoding ignored; nrrdEncodingAscii always used.
".pgm" PGM image file (nrrdFormatPNM) dimension must be 2; type must be uchar can be nrrdEncodingAscii or nrrdEncodingRaw; the output magic will be "P2" or "P5", respectively.
".ppm" PPM image file (nrrdFormatPNM) dimensions must be 3, with first axis 3 samples long; type must be uchar can be nrrdEncodingAscii or nrrdEncodingRaw; the output magic will be "P3" or "P6", respectively.
".png" PNG image file (nrrdFormatPNG) dimensions must be 2 or 3, for 3 with first axis 1-4 samples long; type must be uchar or ushort encoding ingored, nrrdEncodingGzip always used; output magic will be "\211PNG".
".vtk" VTK STRUCTURED_POINTS file (nrrdFormatVTK) dimensions must be 3 (for scalars), or 4, with first axis being 3 (for vectors) or 9 (for tensors) samples long. Type must be uchar, short, int, float, or double. can be nrrdEncodingRaw or nrrdEncodingAscii.
".nhdr" NRRD file (nrrdFormatNRRD) with detached header. Seperate data file will be written with requested encoding, with filename suffix defined in NRRD file format definition
 

Plain text files

Plain, headerless ASCII text files can be read in as 2-D arrays of floats. This is a very useful lowest-common-denominator format for small tabular datasets, such as produced by exporting an Excel spreadsheet of numbers to plain text. This is also the fastest and simplest way to get colormaps into nrrd; here is a file representing a standard rainbow colormap, directly readable by nrrdLoad():
1 0 0
1 1 0
0 1 0
0 1 1
0 0 1
An equivalent NRRD file for this data is:
NRRD0001
type: float
dimension: 2
sizes: 3 5
encoding: ascii

1 0 0
1 1 0
0 1 0
0 1 1
0 0 1
This is how nrrdRead (and _nrrdReadTable()) parse plain text files:
  1. The output Nrrd will always have type float. If its important to have another type, use "unu make -h" to create a detached NRRD header for the data.
  2. The lines of the file can be terminated with either DOS or UNIX style line terminations.
  3. If the file doesn't start with the magic of any other recognized format, then nrrdRead() tries to parse a floating point value from the first line of the file. If this fails, then nrrdRead() fails.
  4. On a line, floating point values are written in ASCII and interpreted according to Section 2 of the NRRD format definition. They can be seperated by one or more characters from the C string " ,\t" (blank, comma, and tab).
  5. _nrrdReadTable() sees how many floats it can parse from the first line (can two be parsed? three? four?) The number of parsable values determines the size of the first axis in the output Nrrd.
  6. Successive lines are read from the file, and with each line, _nrrdReadTable() makes sure it can parse as many numbers as it could parse on the first line. Parsed values are saved in memory as they are read in.
  7. The text file ends with an EOF after the last line termination. The number of lines determines the size of the second axis in the output Nrrd
Just to make things complicated, it is possible to put NRRD field specifiers in the text file, in lines starting with "", which preceed all the ASCII values. nrrdRead() will try to parse everything after "" as field specifiers, according to Section 5 and Section 6 of the NRRD format definition. For instance, the line "# spacings: 1 2" allows the text file to give information about the sample spacing along each axis. Not all field specifiers are valid in text files; here is a list of the ones that are allowed:
content:
dimension:
spacings:
axis mins:
axis maxs:
centers:
labels:
units:
min:
max:
old min:
old max:
The use of dimension is restricted: only "# dimension: 1" and "# dimension: 2" are valid. To further complicate matters, if a lines starts with "#", but cannot be parsed as a nrrd field specifier, than the line is parsed as a plain comment, and saved in the output Nrrd as such.

When writing a Nrrd to a text file (that is, using the nrrdFormatTable format), these field specifiers are by default not written (true as of teem version 1.5beta1). However, this can be explicitly toggled by setting the bareTable field in the NrrdIO passed to nrrdSave() or nrrdWrite(). Or, prior to the creation of the NrrdIO (with nrrdIONew()), change the value of global default nrrdDefWrtBareTable to non-zero.  

PGM/PPM images

Nrrd currently supports binary and ascii PGM/PPM images, in which the indicated maximum value (the third number in the header, after the magic and the two image dimensions) is 255. Different maximum values, and PBM images will be supported as time permits.

_nrrdReadPNM() is a fairly straighforward PGM/PPM reader, but with features which make it more useful. As with text files, nrrd field specifications can be given inside comments in the PGM/PPM header. The prefix to use is "# NRRD>". For example, the comment line "# NRRD>spacings: 1 2" gives spacing information for a PGM (gray-scale, hence 2-dimensional) image. "# NRRD>spacings: nan 1 2" gives the equivalent information for a PPM (color, hence 3-D) image. If a comment does not start with " NRRD>", then it is parsed and saved as a regular comment.

Here is a list of the field specifications valid in PGM/PPM headers (same as are valid for "text" headers above, but minus "dimension"):

content:
spacings:
axis mins:
axis maxs:
centers:
labels:
units:
min:
max:
old min:
old max:

For example, here is the result of resampling a small image down to 16x16, and saving the output (to standard out) as an ascii PGM:

unu resample -i files/fool.pgm -s 16 16 | unu save -f pnm -e ascii

P2
16 16
# NRRD>content: resample(???)
# NRRD>axis mins: 0 0
# NRRD>axis maxs: 127 127
# NRRD>centers: ??? node node
255
86 84 78 71 61 53 47 42 40 39 39 36 51 63 47 65 83 81 74 67 58 59 47 49 50
42 46 41 56 62 44 61 82 79 71 63 52 52 61 66 66 50 53 52 51 62 43 57 80 77
60 46 43 46 46 65 57 49 66 76 63 57 43 50 76 74 43 19 24 28 29 49 42 40 57
91 93 67 45 44 75 67 20 7 18 16 15 36 30 34 41 88 109 96 55 38 74 70 20 4
19 17 20 20 22 36 60 60 89 105 72 29 72 72 24 2 12 29 37 38 33 65 77 65 81
113 80 24 64 64 28 1 10 33 63 69 90 98 77 70 89 99 60 23 21 19 34 19 21 22
55 87 90 126 93 78 103 70 44 24 9 18 33 8 30 29 116 165 167 196 175 85 63
47 46 26 10 11 2 3 29 41 173 207 212 204 118 69 2 38 48 28 11 6 2 7 20 41
162 214 230 82 28 144 108 35 46 29 11 6 4 9 14 45 159 222 138 10 53 143 206
172 65 26 11 5 7 10 23 62 163 144 33 16 69 105 146 219 181 34 11 6 9 7 32
56 69 55 23 19 79 85 88 174 228 79
Note that some nrrd fields have been stored as comments in the output PGM image. The axis mins and axis maxs record the original range of indices that were downsampled, and the centers records the fact that the resampler imposed its default centering (node-centering) since the input image didn't have centering set. When nrrdLoad() or nrrdRead() reads this PGM in, it will parse the "# NRRD>" lines as field specifications, and store the information in the Nrrd struct. In this sense, the encoding of nrrd fields in PNM image comments can be said to be "lossless".  

PNG images

Nrrd also supports PNG images via the libpng library. Nrrd can read any PNG file, including 1,2,4,8,16 bit grayscale (Y), grayscale-alpha (YA), RGB, RGBA, and paletted images, and can write 8 and 16 bit Y, YA, RGB, and RGBA formats. Nrrd field specifications are stored as special PNG comments. The valid field specifications are the same as for PNM images. Gamma and background color transformations are not yet supported in the reader, we apologize for the inconvenience.

For example, here is an example to say HI in PNG land:

unu convert -i - -t uchar -o hi.png
0 0 0 0 0 0 0
0 255 0 255 0 255 0
0 255 255 255 0 255 0
0 255 0 255 0 255 0
0 0 0 0 0 0 0
^D

This creates a small image: hi  

VTK datasets

As of version 1.5, nrrd can read and write VTK datasets on STRUCTURED_POINTS geometries (the dataset structure starts with the line "DATASET STRUCTURED_POINTS"), with the SCALAR, VECTOR, and TENSOR attributes, with either ascii or binary encoding. Only one attribute per file is supported. A description of the VTK file format is available from Kitware.

The VTK format is somewhat less flexible that NRRD in the peripheral information that can be associated with raster data. Because there is no means of saving an arbitrary number of comments, there isn't a way of saving the NRRD information that can be saved into plain text files, and PNG/PPM/PGM images. Here are the correspondances between VTK and NRRD, whereby information in one is saved as the other:

VTK format    NRRD format
"header" (2nd line of file)    content
ASCII    encoding: ascii
BINARY    encoding: raw
DIMENSIONS nx ny nz    sizes: nx ny nz   (scalars)
sizes: 3 nx ny nz   (vectors)
sizes: 9 nx ny nz   (tensors)
ORIGIN x y z    axis mins: x y z   (scalars)
axis mins: NaN x y z   (vectors+tensors)
SPACING sx sy sz    spacings: sx sy sz   (scalars)
spacings: NaN sx sy sz   (vectors+tensors)
SCALARS dataName dataType
VECTORS dataName dataType
TENSORS dataName dataType
   type: dataType

The types allowed in VTK are "bit", "unsigned_char", "short", "int", "float", and "double". The "bit" VTK type is read in as unsigned char (as long as the encoding is ASCII); the other mappings from VTK to NRRD type are as expected. NRRD types which don't fit in VTK will trigger an error in nrrdWrite().

With SCALARS attributes, only "LOOKUP_TABLE default" is allowed, and that is the only lookup table description that nrrd generates.

While the VTK file format description says that only symmetric tensors are supported, all nine elements of the tensor are required. On writing tensors, there is no restriction that the 9 numbers along axis 0 represent a symmetric tensor.

The dataName field in the attribute declaration is ignored on reading. On writing, a dataName of the form "nrrdNNNNN" is generated, where NNNNN is a random 5-digit integer.

Raw ("BINARY") data in a VTK file is always stored big-endian. As usual, nrrd will switch endianness in the data as necessary, depending on the endianness of current platform.