--- title: "NVR File Format Specification" slug: "nvr-file-format-specification" updated: 2026-11-03T16:42:39Z published: 2026-11-03T16:42:39Z canonical: "knowledge.navvis.com/nvr-file-format-specification" --- > ## Documentation Index > Fetch the complete documentation index at: https://knowledge.navvis.com/llms.txt > Use this file to discover all available pages before exploring further. # NVR File Format Specification ## 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] > **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. | ### Footer 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: ```plaintext 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:** ```plaintext GET {archive_url} Range: bytes=-2048 ``` **Response Code & Status:** ```plaintext 206 Partial Content ``` **Response Body:** ```plaintext [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.