NVR File Format Specification

Prev Next

Overview

Use this specification when your application reads panorama tiles or map tiles from IVION. Follow it to find and download individual files in an NVR archive with HTTP Range requests.

The NavVis Archive format (.nvr) is a random-access container for many small files. IVION stores each panorama in one .nvr file, and each map (usually one floor) in one .nvr file. The index of an archive is at its end: a client reads the index once and can then download any file in the archive with a single HTTP Range request.

Note:

  • This article describes the file format. To learn how to find and download the archives of a site, see the Panorama Streaming API Usage Guide and the Map Streaming API Usage Guide.

  • All multi-byte fields are stored in network byte order (big-endian).

File structure

An NVR archive consists of the following parts, in this order:

Part

Size

Description

Header

4 bytes

The signature N, V, R, 0x01.

Payload

Variable

All stored files, back-to-back, in index order. There is no padding between files.

Padding

Variable

Optional 0x00 bytes. The archive is padded so that it is at least 2048 bytes long, so clients can always read the last 2048 bytes of an archive.

Index

4 bytes per file

One uint32 per stored file, containing the length of the file in bytes.

Footer

42 bytes

Metadata about the archive. See the next section.

The footer occupies the last 42 bytes of the archive:

Offset in footer

Type

Description

0

32 bytes

SHA-256 checksum over the stored files.

32

uint32

Number of files stored in the archive.

36

uint8

Archive type: 0 = equirectangular panorama, 1 = cubemap panorama, 2 = tiled map.

37

uint8

File format version. Currently always 0.

38

4 bytes

The signature 0x01, R, V, N.

Locating a file

The first file starts directly after the header, at byte offset 4. Each subsequent file starts where the previous one ends. To compute the byte range of file i, add up the lengths of all files before it:

offset(0) = 4
offset(i) = offset(i - 1) + length(i - 1)
range(i)  = offset(i) .. offset(i) + length(i) - 1   (inclusive)

If a file is missing, for example because a panorama has no depth images, its index entry is present and its length is 0. Skip such files.

Reading an archive over HTTP

Applications download NVR archives from IVION with pre-signed URLs. See the usage guides for how to request one. Reading an archive takes these steps:

  1. Request the last 2048 bytes of the archive with the header Range: bytes=-2048. If the archive is smaller than 2048 bytes, the whole archive is returned.

  2. Read the footer from the last 42 bytes of the response. Check that the last four bytes are 0x01, R, V, N, and read the number of files N and the archive type.

  3. The index occupies the 4 × N bytes directly before the footer. If 4 × N + 42 is larger than the response, request the last 4 × N + 42 bytes of the archive again with Range: bytes=-{4 × N + 42}.

  4. Compute the offset of each file from the index, as described above.

  5. Download a file with the header Range: bytes={offset}-{offset + length - 1}.

For panorama archives, the index and footer have a fixed size (682 or 1002 bytes), so the first request always contains them. Map archives can contain enough tiles to require the second request.

Request:

GET {archive_url}
Range: bytes=-2048

Response Code & Status:

206 Partial Content

Response Body:

[binary data: payload tail, padding, index, footer]

Panorama archives (types 0 and 1)

A panorama archive contains the color tiles of a panorama at four resolution levels, followed by its depth tiles at one resolution level:

Archive type

Projection

Tiles per level

Color tile format

Depth tile format

Number of files

0

Equirectangular

32

JPEG

PNG

160

1

Cubemap

48

WebP

PNG

240

The files are stored in this order, where T is the number of tiles per level:

File indices

Content

0 to T - 1

Color tiles, resolution level 0 (lowest resolution)

T to 2T - 1

Color tiles, resolution level 1

2T to 3T - 1

Color tiles, resolution level 2

3T to 4T - 1

Color tiles, resolution level 3 (highest resolution)

4T to 5T - 1

Depth tiles

The file index of tile t at level r is therefore r × T + t, and the file index of depth tile t is 4 × T + t. The tile layout and the depth encoding are described in the Panorama Streaming API Usage Guide.

Tiled map archives (type 2)

A tiled map archive contains the PNG tiles of a map's tile pyramid. The number of tiles depends on the size and sparsity of the map. The tiles are stored in the same order in which they appear in the map's quadtree: breadth-first, starting with the root tile, and for each tile its children in the order top-left, top-right, bottom-left, bottom-right. The quadtree is described in the Map Streaming API Usage Guide.

FAQ

Why is the index at the end of the file?

The writer adds the index after all files are known. Because the index is at the end, clients can read the index and footer with a single HTTP Range request for the last bytes of the file, without knowing the file size.

Do I need to verify the checksum?

No. The checksum covers the whole payload and is mainly useful to verify complete archives. Clients that download individual files with Range requests usually skip it.

How do I recognize a missing file?

Its index entry has a length of 0. Panorama archives without depth images, for example, have 0-length entries for all depth tiles.