Light Field File Format

Overview:

The light field file format (lif) is a single file that describes a light field. This file has two sections: an ascii header section, and a binary data section. The header contains information such as the number of slabs, spatial geometry, and information about how each slab is stored. The binary section consists of one or more segments. In general, each slab has a segment in the binary section. Other data, such as VQ codebooks for compression, will also have a segment in the binary section. The details of each data segment (size, data type, etc) are described in the header.

File Name:

Light field files should generally end with the .lif extension.

Header (General):

The header consists of lines of ascii text, and may be of variable size. The first line of the header must be:
	LIF1.0
The last line of the header must be the line:
	endheader
Following this line is the ascii character \0. The character immediately following \0 is the first byte (byte 0) of the data segment.

Whitespace is ignored in the header. Thus a single statement may occupy multiple lines.

Comments may appear anywhere in the header between the beginning and ending lines. The beginning of a comment is marked with #, and continues to the end of the line. For example:

	LIF1.0
	# Plastic Lion Lightfield
	# Created by Marc Levoy, 12-24-95
	datasize 135987200	# current size of data section

	bgnlightfield 1
	slabs 4    		# view from south, west, north, east.
	.
	.
	.
	endlightfield
	endheader

Header (Contents):

Before the lightfield definitions, we list the current size of the data segment. This is the offset at which more segments or channels can be added.
	datasize 135987200	# current size of data section
A lightfield definition begins with the line:
	bgnlightfield 1
Then it contains general information that applies to the entire lightfield. The first line should list the number of slabs in the lightfield. For example:
	slabs 4    		# view from south, west, north, east.
Following this general information, the header contains a description of each data segment. Each description should start with bgnsegment <type>, and end with endsegment. Each segment may contain one or more channels. A channel is the basic contiguous block of storage.

Required information for each channel is the data type, the offset of the channel into the file (offset is relative to the \0 character that marks the end of the header), and the size of the channel (in bytes).

A segment description also includes other information specific to that type of segment. For example, a slab segment will also list the slab dimensions, slab geometry, etc. A vector-quantization codebook segment will list the number of tiles, tile dimensions, etc.

For example, a slab segment might look like this:

	  bgnsegment slab 1
	    compression none
	    format rgba
	    bgnchannel rgba	# ---- red, green, blue, alpha channel ----
	      type int8x4
	      offset 0
	      size 67108864
	    endchannel
	    samples_uv 16 16
	    samples_st 256 256 
	    geometry_uv -2 -2 2 1   0 0  # 6 numbers: x,y,z,w, q,r
 	  	         2 -2 2 1   1 0
		         2  2 2 1   1 1
		        -2  2 2 1   0 1
	    geometry_st -1 -1 0 1   0 0 
		         1 -1 0 1   1 0
		         1  1 0 1   1 1
		        -1  1 0 1   0 1
	  endsegment 
The lightfield definition ends with the line:
	endlightfield

Header (Example):

This is what a full header might look like, for a lightfield with two slabs. the second slab is vector-quantization compressed, but the first one is not.
	LIF1.0
	# Plastic Lion Lightfield
	# Created by Marc Levoy, 12-24-95

	datasize 69402624	# current size of data section

	bgnlightfield 1
	  slabs 2

	  # front side
	  bgnsegment slab 0
	    compression none
	    format rgba
	    bgnchannel rgba	# ---- red, green, blue, alpha channel ----
	      type int8x4
	      offset 0
	      size 67108864
	    endchannel
	    samples_uv 16 16
	    samples_st 256 256 
	    geometry_uv
			-2 -2 2 1   0 0
 	  	         2 -2 2 1   1 0
		         2  2 2 1   1 1
		        -2  2 2 1   0 1
	    geometry_st 
			-1 -1 0 1   0 0 
		         1 -1 0 1   1 0
		         1  1 0 1   1 1
		        -1  1 0 1   0 1
	  endsegment # 0

	  # back side
	  bgnsegment slab 1
	    compression vq 0	# Use vector-quantization codebook #0
	    format index
	    bgnchannel index	# ---- codebook index channel ----
	      type int16
	      offset 67108864
	      size 2097152
	    endchannel
	    samples_uv 16 16
	    samples_st 256 256 
	    geometry_uv 
			 2 -2 -2 1   0 0
 	  	        -2 -2 -2 1   1 0
		        -2  2 -2 1   1 1
		         2  2 -2 1   0 1
	    geometry_st 
			 1 -1 0 1   0 0 
		        -1 -1 0 1   1 0
		        -1  1 0 1   1 1
		         1  1 0 1   0 1
	  endsegment # 1

	  # vq codebook (used for slab 1)
	  bgnsegment vq 0
	    format rgb
	    bgnchannel rgb	# ---- red, green, blue channel ----
	      type int8x3
	      offset 69206016
	      size 196608
	    endchannel
	    tiles 4096
	    tilesize 2 2 2 2	# size of the tiles, in u, v, s, t
	  endsegment # vq 0

	endlightfield
	endheader

Data (Contents):

Each segment of data contains the necessary binary information. For uncompressed slabs, this will be the raw r,g,b[,a] values for each ray. For VQ-compressed slabs, it will be the codebook indices. For VQ-codebooks, it will be the r,g,b[,a] values for each tile of the codebook.

Data (Management):

If a slab changes size (for example, if it is upsampled), then it may need more storage space than it currently has. In this case, we can move some of the channels to the end of the file, and give it as much space as it needs. We would update the offset information in the header to reflect this change.

Since we can move segments/channels around, we may end up with "garbage" segments that are no longer occupied. These garbage segments should be cleared to a constant value (to allow efficient compression of the file). It would be possible to occasionally "compact" the file, getting rid of unused segments and updating the pointers in the header.