ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/doc/filefmts.md
Revision: 1.1
Committed: Thu Nov 10 18:05:39 2022 UTC (18 months, 1 week ago) by greg
Branch: MAIN
Log Message:
docs(filefmts): recovered file formats document from Randolph Fritz (thanks!!)

File Contents

# User Rev Content
1 greg 1.1 # *Radiance* File Formats
2     This chapter discusses the standard file formats specific to *Radiance*, and gives their internal structure, with pointers to routines for reading and writing them. The following file formats (listed with their conventional suffixes) are covered:
3    
4     Scene Description (.rad suffix)
5     : This is the main input file type, describing materials and geometry for the rendering programs, and must be compiled into an octree by oconv prior to ray-tracing. It is an ASCII text format, and is often translated from a CAD description, but may be created or edited by a text editor as well.
6    
7     Function File (.cal suffix)
8     : Also a text format, these files describe mathematical patterns, textures, and surface shapes. In the case of patterns and textures, the functions serve as input directly to the rendering programs. In the case of surfaces, the functions serve as input to one of the generator programs, **gensurf**, **genrev** or **genworm**. Additionally, **pcomb** may be used to perform math on *Radiance* pictures and the **rcalc** utility may be used in creative ways to manipulate data for scene generation and data analysis.
9    
10     Data File (.dat suffix)
11     : Another ASCII format, data files are used directly by the rendering programs to interpolate values for luminaire photometry, among other things.
12    
13     Font File (.fnt suffix)
14     : A simple, polygonal font representation for rendering text patterns. This ASCII format describes each character "glyph" as a sequence of vertices in rectangular, integer coordinates ranging from 0 to 255.
15    
16     Octree (.oct suffix)
17     : A binary data structure computed from one or more scene description files by the oconv program. It may contain frozen scene data in binary form, or merely references to the original scene files.
18    
19     Picture (.hdr suffix)
20     : A binary image file containing calibrated, real radiance values at each pixel. *Radiance* pictures may be displayed, analyzed, and converted to other image formats.
21    
22     Z-buffer (.zbf suffix)
23     : A binary file with the distances to each pixel in a corresponding picture.
24    
25     Ambient File (.amb suffix)
26     : A binary file used to store diffuse interreflection values, which are shared between cooperating rendering processes running sequentially or in parallel. Since these values are view-independent, sharing this information across multiple runs is highly economical.
27    
28     We will discuss each of these formats in turn, giving examples and pointers to routines in the source code for reading and writing them, and the programs that use them. In general, the ASCII text formats have no standard routines for writing them, since they generally originate outside of *Radiance* or are created with simple *printf(3)* statements. Most binary file formats are machine and system independent, meaning they can be moved safely from one place to another and *Radiance* will still understand them (provided no unintentional character translation takes place along the way)[^1]. Most binary files also include a standard ASCII header at their beginning that may be read by the **getinfo** program. This offers a convenient method for identifying the file contents when the file name is ambiguous.
29    
30     [^1]: The single exception to this rule is the Z-buffer file, whose contents are dictated by the floating point representation and byte order of the originating machine. This choice was made for economic reasons, and is rarely a problem.
31    
32     ## Scene Description Format (.rad suffix)
33     The semantics of the *Radiance* scene description format are covered in the Reference Manual. We will therefore focus on the file syntax and structure, which are simple and straightforward. In fact, some would say that the *Radiance* scene description format is brain-dead, in the sense that it offers few language amenities and requires the awkward counting of string and real arguments (not to mention those non-existent integer arguments). We have little to offer in its defense.
34    
35     The truth is, the scene format was designed to grow with *Radiance*, and we wanted to keep it as simple as possible so as to encourage others to write translators to and from it. Specifically, we wanted to be able to read files using the *scanf(3)* library function and write files using *printf(3)*. Furthermore, we wanted everyone's parsers to be stable over time, which meant no primitive-specific syntax. We also decided that a flat file structure was most practical, since hierarchies are typically lost on the first translation, and sufficient structure could be provided by the file system itself. Since we did not intend text editing to be the primary input method, we felt the effects of these programming decisions on the human readability and writability of the format were less important.
36    
37     Even so, the format is relatively easy to read and write once you get used to it, and with the *Radiance* generator programs and in-line command expansion, the text editor becomes a powerful modeling tool in the hands of an experienced user. Together with the need for editing material descriptions, our assumption that users would rarely edit these files turned out to be mistaken. Consequently, it is a good idea for all users to familiarize themselves with the scene description format, awkward or not.
38    
39     ### Basic File Structure
40     There are four statement types in a scene description file: comments, commands, primitives and aliases. These may be interspersed in the file, and the only structural requirement is that modifiers precede the primitives they modify.
41    
42     #### Comments
43     The simplest statement type is a comment statement begins with a pound sign ('#') and continues to the end of line:
44    
45     # This is a comment.
46    
47     #### Commands
48     An in-line command, which begins with an exclamation mark ('!') and continues to the end of line:
49    
50     !xform -n chair1 -t 10 5 8 chair.rad
51    
52     The command is executed during file parsing, and its output is read as more input. Long commands may be continued on multiple lines by escaping the newline character with a backslash ('\'):
53    
54     !gensurf marble sink '15.5+x(theta(s),phi(t))' \
55     '10.5+y(theta(s),phi(t))' \
56     '30.75+z(theta(s),phi(t))' \
57     8 29 -f basin.cal -s
58    
59     Since the command is executed by the shell, pipes and other facilities are available as well. The following command creates a counter with a precisely cut hole for the sink basin just given:
60    
61     !( echo marble polygon sink_top 0 0 108 31 \
62     10.5 30.75 31 22 30.75 0 22 30.75 0 0 \
63     30.75 31 0 30.75 31 10.5 30.75 ; \
64     cnt 30 | rcalc \
65     -e '$1=15.5+x(theta(0),phi(1-$1/29))' \
66     -e '$2=10.5+y(theta(0),phi(1-$1/29))' \
67     -e '$3=30.75' -f basin.cal )
68    
69     Note in the above example that two commands are executed in sequence. The first creates the counter perimeter, and the second cuts the hole. The two commands are enclosed in parentheses, so if a final transformation is added by **xform** with the **-c** option, it will be applied to both commands, not just the last one.
70    
71     #### Primitives
72     A primitive can be thought of as an indivisible unit of scene information. It can be a surface, material, pattern, texture or mixture. The basic structure of a primitive is as follows:
73    
74     modifier type identifier
75     n S1 S2 S3 ..Sn
76     0
77     m R1 R2 R3 ..Rm
78    
79     The `modifier` is the `identifier` of a previously defined primitive, or `void` if no modifier is appropriate. The type is one of the supported *Radiance* primitive keywords, such as *polygon* or *plastic*. Following the `modifier`, type and identifier are the string arguments, preceded by the number of string arguments and separated by white space. If there are no string arguments, then 0 should be given for `n`. The string arguments are followed by the integer arguments in the same fashion. (Since there are no *Radiance* primitives currently using integer arguments, the count is always 0.) Finally, the number of real arguments is given, followed by the real arguments.
80    
81     The location of the primitive in the scene description has no importance, except that its modifier refers to the most recently defined primitive with that identifier. If no such modifier was defined, an error results. In fact, “undefined modifier” is the most frequently reported error when parsing an invalid scene description, since any random bit of junk encountered where a statement is expected will be interpreted as a modifier. One final note about modifiers — since surfaces never modify anything, their identifiers are neither stored nor referenced in the parser's modifier list, and serve only for debugging purposes during editing and rendering.
82    
83     Within a primitive, white space serves only to separate words, and multiple spaces, tabs, form feeds, returns, and newlines are all considered as one separator. Consequently, it is not possible for a string argument to contain any white space, which is OK because no *Radiance* primitive needs this.
84    
85     #### Aliases
86     An alias simply associates a new modifier and identifier with a previously defined primitive. The syntax is as follows:
87    
88     modifier alias new_identifier old_identifier
89    
90    
91     The `old_identifier` should be associated with some modifier primitive (i.e., non-surface) given earlier. The `modifier`, if different from the original, will be used instead in later applications of `new_identifier`.
92    
93     Aliases are most often used to give new names to previously defined materials. They may also be used to associate different patterns or textures with the same material.
94    
95     ### Scene Hierarchy
96     Hierarchical scene descriptions are achieved through expansion of in-line **xform** commands. The **xform** command is used to read and place other *Radiance* scene description files in the calling file, and these other descriptions may in turn read others, and so on down the tree. No check is made to assure that none of the calling files is called again, even by itself. If this happens, commands open commands until the system runs out of processes, which is a very nasty business and to be avoided.
97    
98     ### *Radiance* Programs
99     The following table shows programs in the main *Radiance* distribution that read and write scene description files. Additionally, there are other translators that write scene files, which are available separately as free contributions or as part of other (CAD) programs.
100    
101     |Program|Read|Write|Function|
102     |-------|----|-----|--------|
103     **arch2rad** ||X|Convert Architrion text file to *Radiance*
104     **genblinds**||X|Generate curved venetian blinds
105     **genbox** ||X|Generate parallelepiped
106     **genclock** ||X|Generate analog clock
107     **genprism** ||X|Generate extruded polygon
108     **genrev** ||X|Generate surface of revolution
109     **gensky** ||X|Generate CIE sky distribution
110     **gensurf** ||X|Generate arbitrary surface patch
111     **genworm** ||X|Generate varying diameter curved path
112     **ies2rad** ||X|Convert IES luminaire file to *Radiance*
113     **mgf2rad** ||X|Convert MGF file to *Radiance*
114     **mkillum** |X|X|Compute *illum* secondary sources
115     **nff2rad** ||X|Convert NFF file to *Radiance*
116     **objline** ||X|Generate line drawing of *Radiance* file
117     **objview** ||X|Quick view of *Radiance* object
118     **oconv** ||X|Compile *Radiance* scene description
119     **obj2rad** ||X|Convert Wavefront .OBJ file to *Radiance*
120     **rad** |X|| Render *Radiance* scene
121     **rad2mgf** |X|| Convert *Radiance* file to MGF
122     **raddepend** |X|| Determine scene file dependencies
123     **replmarks** |X|X| Replace triangular markers with objects
124     **rpict** |X|| Batch rendering program
125     **rtrace** |X|| Customizable ray-tracer
126     **rview** |X|| Interactive renderer
127     **thf2rad** ||X| Convert GDS things file to *Radiance*
128     **tmesh2rad**||X| Convert triangle mesh file to *Radiance*
129     **xform** |X|X|Transform Radiance objects
130    
131     **Table 1.** Radiance programs that read and write scene descriptions.
132    
133     ### *Radiance* C Library
134     The principal library function for reading scene description files is `readobj(inpspec)`, defined in `src/common/readobj.c`. This routine takes the name of a file, or command beginning with ‘!’, or `NULL` if standard input is to be read, and loads the *Radiance* data structures defined in `src/common/object.h`. If loading *Radiance* data structures is not the action desired, then a more custom approach is necessary, such as that used in `src/gen/xform.c`. If using *Radiance* data structures is acceptable, but the data need not remain resident in memory, then follow the lead in `src/ot/getbbox.c` and use `src/ot/readobj2.c` instead. In any case, the list of defined primitive types in `src/common/otypes.h` is crucial.
135    
136     ## Function File Format (.cal suffix)
137     Function files are used throughout *Radiance* to specify mathematical formulas and relations for procedural textures, patterns and surfaces. They are also used by filter programs such as rcalc to manipulate data, and pcomb to manipulate pictures.
138    
139     Function file syntax is simple and should be familiar to most programmers, as it is based on fairly standard algebraic expressions. Here is an example, which corresponds to the in-line commands given in the previous section:
140    
141     {
142     basin.cal - calculate coordinates for basin sink.
143     }
144    
145     theta(s) = PI*(0.5+0.5*s);
146     phi(t) = 2*PI*t;
147    
148     R(th,p) = 5 + ( 3.25*cos(p)^2 +
149     1.75*sin(p)^2 ) * sin(th)^2;
150    
151     x(th,p) = R(th,p)*sin(th)*cos(p);
152     y(th,p) = R(th,p)*sin(th)*sin(p);
153     z(th,p) = R(th,p)*cos(th);
154    
155     In contrast to the usual semantics in programs where each statement corresponds to an evaluation, statements in function files correspond to *definitions*. Once a function or variable has been defined, it may be used in later definitions, along with predefined functions such as `sin(x)` and `cos(x)` and constants such as PI [^2]. (All math functions use standard C conventions, hence trigonometry is done in radians rather than degrees.)
156    
157     [^2]: TBD - There once was a footnote here
158    
159     Evaluation order (operator precedence) follows standard rules of algebra. Exponentiation is performed first `(x^y)`, followed by multiplication and division `(x*y, x/y)`, then addition and subtraction `(x+y, x-y)`. Unary minus is most tightly associated `(-x)`, and parentheses override operator precedence in the usual way. Semicolons separate statements, and white space is generally ignored. Comments are enclosed by curly braces, which may be nested.
160    
161     The above file does not actually *do* anything, it merely defines functions that are useful by a program that does. Taking our **gensurf** example from the previous section:
162    
163     !gensurf marble sink '15.5+x(theta(s),phi(t))' \
164     '10.5+y(theta(s),phi(t))' \
165     '30.75+z(theta(s),phi(t))' \
166     8 29 -f basin.cal -s
167    
168     The **-f** option loads in our file, which is then used to evaluate expressions such as `15.5+x(theta(s),phi(t))` for specific values of `s` and `t`. These variables range from 0 to 1 over the surface patch in increments of $1/8$ and $1/29$, respectively. (See the **gensurf** manual page for details.) The entire expression for each evaluation could have been written in the command line, but it is much more convenient to create a function file.
169    
170     ### Language Features
171    
172     Subtle features of the functional language provide much greater power than first meets the eye. One of these is the ability to define recursive functions. The following example defines the factorial function (*n!*):
173    
174     fact(n) : if(n-1.5, n*fact(n-1), 1);
175    
176     This uses the library function `if(cond,e1,e0)`, which returns `e1` if cond is greater than zero, and `e0` otherwise. Since only one of these expressions is evaluated, `fact(n)` will call itself until `n` is less than 2, when
177     the `if` expression returns 1[^3]. The colon (':') is used in place of the usual equals assignment ('=') because we want this function to have the constant attribute, which means any later appearance in an expression of `fact(ce)` where ce is also a constant expression will be replaced by its value. This can be an important savings in cases where an expression or subexpression is expensive to evaluate, and only needs to be computed once. All of the standard library functions have the constant attribute. (See the following section for a complete list.)
178    
179     [^3]: Note that we compare `n` to 1.5, so as to avoid any round-off problems caused by floating point math. Caution is advised because all expressions are evaluated as double-precision real, and comparisons to zero are unreliable.
180    
181     Another handy language feature is the ability to pass function names as arguments. A simple example of this is the following function, which computes the numerical derivative of a function given as its first argument:
182    
183     FTINY : 1e-7;
184     d1(f,x) = (f(x+FTINY)-f(x-FTINY))/FTINY/2;
185    
186     Evaluating `d1(sin,1.1)` using this formula yields 0.4536, which is fairly close to the true derivative, which is `cos(1.1)`.
187    
188     A third language feature, which is normally transparent to the user, is the notion of *contexts*. Identifiers may be composed of parts, starting with a name and continuing with one or more context names. Each name is delimited by a back-quote ('\`'). Names themselves begin with a letter and continue with any sequence of letters, digits, underscores and decimal points. The following are examples of valid identifiers:
189    
190     v1, V.W, x_rand`local, `A_, Qa_5`
191    
192     If a context mark appears at the beginning of the identifier, then its reference must be local. If it appears at the end, then its reference must be global. A local reference must be resolved in the local context, i.e., no contexts above this one will be searched. A global reference must correspond to the original context, ignoring any local redefinitions.
193    
194     The reason that contexts are normally transparent is that they are controlled by the calling program — there are no explicit language features for establishing contexts. A new context is established automatically for each function file loaded by the rendering programs. That way, it is safe to reuse variable names that have been used in other files, and even in the main initialization file, `rayinit.cal`.
195    
196     Although not strictly necessary, there are two good reasons to define variables and functions before referencing them in a function file. One is related to contexts. If a previous definition of a variable name is given in an enclosing context (e.g., `rayinit.cal`), then that reference will be used rather than a later one in the current context, unless the reference is made explicitly local by starting the identifier with a context mark. The second reason for defining before referencing is constant expressions. If a variable or function has the constant attribute (i.e., defined with ':' instead of '='), then a later subexpression referencing it can be replaced by its evaluated result during compilation. If the constant is not defined until after it is referenced, it remains as a reference, which takes time to evaluate each time.
197    
198     Other features of the language are truly transparent, but knowledge of them can help one to write more efficient function files:
199    
200     - Once a variable has been evaluated, the result is cached and it is not reevaluated unless the client program changes an internal counter (`eclock`), which indicates that something has changed. This means that using variables to hold frequently used values will not only simplify the function file, it will save time during evaluation.
201    
202     - An argument passed in a function call is not evaluated until the function calls for it specifically, and the result is also cached to avoid redundant calculation. The conditional evaluation feature is actually a requirement for recursive functions to work, but caching is not. Argument value caching means it is more efficient to pass an expensive-to-compute expression than to have the function compute it internally if it appears more than once in the function definition. This is especially true for recursive functions with deep call trees.
203    
204     ### Standard Definitions (Library)
205    
206     The following are always defined:
207    
208     `if(a, b, c)`
209     : Conditional expression. If a is positive, return b, else return c.
210    
211     `select(N, a1, a2, ..)`
212     : Return Nth argument. If N is 0, then return the count of arguments excluding the first. This provides basic array functionality.
213    
214     `sqrt(x)`
215     : Return square root of `x`, where `x >= 0`.
216    
217     `sin(x), cos(x), tan(x), asin(x), acos(x), atan(x), atan2(y,x)`
218     : Standard trigonometry functions.
219    
220     `floor(x), ceil(x)`
221     : Greatest lower bound and least upper bound (integer).
222    
223     `exp(x), log(x), log10(x)`
224     : Exponent and logarithm functions.
225    
226     `rand(x)`
227     : Return pseudo-random number in the range [0,1) for any argument x. The same return value is guaranteed for the same argument.
228    
229     The following are sometimes defined, depending on the program:
230    
231     PI
232     : The ratio of a circle's circumference to its diameter.
233    
234     `erf(z), erfc(z)`
235     : Error function and complimentary error function.
236    
237     `j0(x), j1(x), jn(n,x), y0(x), y1(x), yn(n,x)`
238     : Bessel functions.
239    
240     `hermite(p0,p1,r0,r1,t)`
241     : One-dimensional Hermite polynomial.
242    
243     The rendering programs also define the following noise functions:
244    
245     `noise3(x,y,z), noise3x(x,y,z), noise3y(x,y,z), noise3z(x,y,z)`
246     : Perlin noise function and its gradient [Perlin85][Arvo91,p.396].
247    
248     `fnoise3(x,y,z)`
249     : Fractal noise function, ranging from -1 to 1.
250    
251     Interaction with the renderer is achieved via special purpose variables and functions whose values correspond to the current ray intersection and the calling primitive. Unlike the above functions, none of these have the constant attribute since their values change from one ray to the next:
252    
253     `Dx, Dy, Dz`
254     : ray direction
255    
256     `Nx, Ny, Nz`
257     : surface normal
258    
259     `Px, Py, Pz`
260     :intersection point
261    
262     `T`
263     : distance from start
264    
265     `Ts`
266     : single ray (shadow) distance
267    
268     `Rdot`
269     : ray dot product
270    
271     `S`
272     : world scale
273    
274     `Tx, Ty, Tz`
275     : world origin
276    
277     `Ix, Iy, Iz`
278     : world i unit vector
279    
280     `Jx, Jy, Jz`
281     : world j unit vector
282    
283     `Kx, Ky, Kz`
284     : world k unit vector
285    
286     `arg(n)`
287     : real arguments, arg(0) is count
288    
289     For BRDF primitives, the following variables are also available:
290    
291     `NxP, NyP, NzP`
292     : perturbed surface normal
293    
294     `RdotP`
295     : perturbed ray dot product
296    
297     `CrP, CgP, CbP`
298     : perturbed material color
299    
300     For prism1 and prism2 primitives, the following are available:
301    
302     `DxA, DyA, DzA`
303     : direction to target light source
304    
305     Other functions, variables and constants are defined as well in the file `src/rt/rayinit.cal`, which gets installed in the standard *Radiance* library directory and can be modified or appended as desired[^4].
306    
307     [^4]: It is usually a good idea to store any such customized files in a personal library location and set the `RAYPATH` environment variable to search there first. This way, it does not affect other users or get overwritten during the next system installation.
308    
309     ### *Radiance* Programs
310     Table 2 shows *Radiance* programs that read and write function files.
311    
312     |Program | Read | Write | Function
313     |--------|------|-------|---------
314     **calc** | X |X | Interactive calculator
315     **genrev** | X || Generate surface of revolution
316     **gensurf** | X || Generate arbitrary surface patch
317     **genworm** | X || Generate varying diameter curved path
318     **macbethcal** || X | Compute image color & contrast correction
319     **pcomb**| X || Perform arbitrary math on picture(s)
320     **rcalc**| X || Record stream calculator
321     **rpict**| X || Batch rendering program
322     **rtrace** | X || Customizable ray-tracer
323     **rview**| X || Interactive renderer
324     **tabfunc** || X | Create function file from tabulated data
325    
326     **Table 2.** Programs in the *Radiance* distribution that read and write function files.
327    
328     In addition, the program **ev** evaluates expressions given as command line arguments, though it does not handle function files or definitions. There are also a number of 2-d plotting routines that use a slightly modified statement syntax, called **bgraph**, **dgraph**, **gcomp**, and **igraph**. Additional utility programs are useful in combination with rcalc for data analysis and scene generation. The program **cnt** generates simple records to drive **rcalc**, and the **total** program is handy for adding up results. The **histo** program computes histograms needed for certain types of statistical analysis. The **lam** program concatenates columns from multiple input files, and **neat** neatens up columns for better display.
329    
330     ### *Radiance* C Library
331     The standard routines for loading and evaluating function files are divided into three modules, `src/common/calexpr.c` for expression parsing and evaluation, `src/common/caldefn.c` for variable and function storage and lookup, and `src/common/calfunc.c` for library function storage and function evaluation. There is a fourth module for writing out expressions called `src/common/calprnt.c`, which we will not discuss. They all use the header file `src/common/calcomp.h`, which defines common data structures and evaluation macros. Of these, the three most often used declarations for external routines are:
332    
333     `typedef struct epnode EPNODE;`
334     : Expression parse tree node. Some routines return pointers to this structure type, and the main evaluation macro, `evalue(ep)`, takes an argument of this type.
335    
336     `(double) evalue(ep);`
337     : Evaluate an expression parse tree. Uses node type table to access appropriate function depending on root node type. (E.g., an addition node calls `eadd(ep)`.)
338    
339     `extern unsigned long eclock;`
340     : This is a counter used to determine when variable values need updating. The initial value is 0, which tells the routines always to reevaluate variables. Once incremented to 1, variable evaluations are cached and not recomputed until `eclock` is incremented again. Usually, client programs increment `eclock` each time definitions or internal states affecting returned values change. This assures the quickest evaluation of correct results.
341    
342     The usual approach to handling definitions is to compile them into the central lookup table; variable and function references are later evaluated by traversing the stored parse trees. Syntax errors and undefined symbol errors during evaluation result in calls to the user-definable routine `eputs(s)` to report the error and `quit(status)` to exit the program. Domain and range errors during evaluation set `errno`, then call the user-definable routine `wputs(s)` to report the error and return zero as the expression result.
343     Following are standard routines provided for parsing from a file and parsing from a string:
344    
345     `EPNODE *eparse(char *expr);`
346     : Compile the string expr into a parse tree for later evaluation with evalue(ep).
347    
348     `epfree(EPNODE *ep);`
349     : Free memory associated with ep, including any variables
350     referenced if they are no longer defined.
351    
352     `double eval(char *expr);`
353     : Immediately parse, evaluate and free the given string expression.
354    
355     `fcompile(char *fname);`
356     : Compile definitions from the given file, or standard input if fname is NULL.
357    
358     `scompile(char *str, char *fn, int ln);`
359     : Compile definitions from the string str, taken from file fn at line number ln. If no file is associated, fn can be NULL, and ln can be 0.
360    
361     The following routines allow one to control the current context for definition lookup and storage:
362    
363     `char *setcontext(char *ctx);`
364     : Set the current context to ctx. If ctx is NULL, then simply return the current context. An empty string sets the global context.
365    
366     `char *pushcontext(char *name);`
367     : Push another context onto the stack. Return the new (full)
368     context.
369    
370     `char *popcontext();`
371     : Pop the top context name off the stack. Return the new (full) context.
372    
373     The following functions permit the explicit setting of variable and function values:
374    
375     `varset(char *vname, int assign, double val);`
376     : Set the specified variable to the given value, using a constant assignment if assign is ':' or a regular one if it is '='. This is always faster than compiling a string to do the same thing.
377    
378     `funset(char *fname, int nargs, int assign, double (*fptr)(char *fn));`
379     : Assign the specified library function, which takes a minimum of nargs arguments. The function will have the constant attribute if assign is ':', or not if it is '='. The only argument to the referenced function pointer is the function name, which will equal fname. (This string must therefore be declared static.) This offers a convenient method to identify calls to an identical function assigned multiple tasks. Argument values are obtained with calls back to the argument(n) library function.
380    
381     The following functions are provided for evaluating a function or variable in the current definition set:
382    
383     `double varvalue(char *vname);`
384     : Evaluate the given variable and return the result. Since a hash lookup is necessary to resolve the reference, this is slightly less efficient than evaluating a compiled expression via evalue(ep), which uses soft links generated and maintained during compilation.
385    
386     `double funvalue(char *fn, int n, double a);`
387     : Evaluate the function fn, passing n real arguments in the array a. There is currently no mechanism for passing functions or function name arguments from client programs.
388    
389     These routines can be used to check the existence of a specific function or variable:
390    
391     `int vardefined(char *vname);`
392     : Return non-zero if the named variable is defined. (If the symbol
393     is defined as a function, zero is returned.)
394    
395     `int fundefined(char *fname);`
396     : Return the number of required arguments for the named function if it is defined, or zero if it is not defined. (If the symbol is defined as a variable, zero is returned.)
397    
398     These routines allow definitions to be cleared:
399    
400     `dclear(char *dname);`
401     : Clear the given variable or function, unless it is a constant expression.
402    
403     `dremove(char *dname);`
404     : Clear the given variable or function, even if it is a constant expression. Library definitions cannot be removed, except by calling funset with a `NULL` pointer for the function argument.
405    
406     `dcleanup(int level);`
407     : Clear definitions. If level is 0, then just clear variable definitions. If level is 2, then clear constants as well. If the current context is local, then only local definitions will be affected. If global, all definitions in all contexts will be affected.
408    
409     These routines may be used during library function evaluation:
410    
411     `int nargum();`
412     : Determine the number of arguments available in the current
413     function evaluation context.
414    
415     `double argument(int n);`
416     : Evaluate and return the nth argument.
417    
418     `char *argfun(n);`
419     : Get the name of the function passed as argument n. (Generates an error if the nth argument is not a function.)
420    
421     Other, even more specialized routines are provided for controlling the parsing process, printing out expressions and sifting through stored definitions, but these are not accessed by most client programs. Worth noting are the various compile flags that affect which features of the expression language are included. The standard library sets the flags `-DVARIABLE`, `-DFUNCTION`, `-DRCONST`, and `-DBIGLIB`. Here is a list of compile flags and their meanings:
422    
423     `-DVARIABLE`
424     : Allow user-defined variables and (if `-DFUNCTION`) user-
425     defined functions.
426    
427     `-DFUNCTION`
428     : Compile in library functions and (if `-DVARIABLE`) allow user-supplied function definitions.
429    
430     `-DBIGLIB`
431     : Include larger library of standard functions, i.e., standard C math library. Otherwise, only minimal library is compiled in, and other functions may be added using `funset`.
432    
433     `-DRCONST`
434     : Reduce constant subexpressions during compilation. This can result in substantial savings during later evaluation, but the original user-supplied expressions are lost.
435    
436     `-DREDEFW`
437     : Issue a warning via `wputs(s)` if a new definition hides a constant definition or library function, or replaces an existing, distinct definition for the same symbol. (The `varset` routine never generates warnings, however.)
438    
439     `-DINCHAN`
440     : Provide for `\$N` syntax for input channels, which result in callbacks to client-supplied chanvalue(n) routine on each evaluation.
441    
442     `-DOUTCHAN`
443     : Provide for `\$N` lvalue syntax for output channels, which are evaluated via the chanout(cs) library function, which calls `(*cs)(n, value)`for each assigned channel definition.
444    
445     ## Data File Format (.dat suffix)
446     Although it is possible to store tabular data in a function file using the select library function, it is more convenient and efficient to devote a special file format to this purpose. *Radiance* data files store scalar values on an N-dimensional rectangular grid. Grid (independent) axes may be regularly or irregularly divided, as shown in Figure 1. This data is interpolated during rendering (using N-dimensional linear interpolation) to compute the desired values.
447    
448     ![Division of axes in .dat file](figure1.svg)
449    
450     **Figure 1.** A 2-dimensional grid with one regularly divided axis and one irregularly divided axis. Each intersection corresponds to a data value that
451     appears in the file.
452    
453     Data files are broken into two sections, the header and the body. The header specifies the grid, and the body contains the data values in a standard order. The first value in the file is a positive integer indicating the number of dimensions. Next comes that number of axis specifications, in one of two formats. For a regularly divided axis, the starting and ending value is given, followed by the number of divisions. For an irregularly divided axis, two zeros are followed by the number of divisions then that number of division values. The two zeros are merely there to indicate an irregular spacing is being specified. Once all the axes have been given, the header is done and the body of the file begins, which consists of one data value after another. The ordering of the data is such that the last axis given is the one being traversed most rapidly, similar to a static array assignment in C.
454    
455     A file corresponding to the topology shown in Figure 1 is:
456    
457     ######### Header ########
458     2 # Two-dimensional data array
459     0.5 0.1 5 # The regularly spaced axis
460     0 0 5 3 5 10 16 20 # The irregularly spaced axis
461     ########## Body #########
462     # The data values, starting with the
463     # upper left, moving right then down:
464     19.089 7.001 14.647 6.3671 8.0003
465     3.8388 11.873 19.294 16.605 2.7435
466     16.699 6.387 2.8123 16.195 17.615
467     14.36 14.413 16.184 15.635 4.5403
468     3.6740 14.550 10.332 15.932 1.2678
469    
470     Comments begin with a pound sign ('#') and continue to the end of the line. White space is ignored except as a data separator, thus the position of header and data values on each line is irrelevant except to improve readability.
471    
472     ### *Radiance* Programs
473     Table 3 shows *Radiance* programs that read and write data files.
474    
475     Program | Read | Write | Function
476     ----------- | ---- | ----- | --------
477     **ies2rad** || X | Convert IES luminaire file to *Radiance*
478     **mgf2rad** || X | Convert MGF file to *Radiance*
479     **rpict** | X || Batch rendering program
480     **rtrace** | X || Customizable ray-tracer
481     **rview** | X || Interactive renderer
482    
483     **Table 3.** Programs in the *Radiance* distribution that read and write data files.
484    
485     ### *Radiance* C Library
486     The header file `src/rt/data.h` gives the standard data structures used by the routines in `src/rt/data.c` for reading and interpolating data files. The main data type is `DATARRAY`, which is a structure containing the grid specification and a pointer to the data array, which is of the type `DATATYPE` (normally **float** to save space).
487    
488     The main routine for reading data files is `getdata(dname)`, which searches the standard *Radiance* library locations set by the `RAYPATH` environment variable. The return value is a pointer to the loaded `DATARRAY`, which may have been loaded by a previous call. (The routine keeps a hash table of loaded files to minimize time and memory requirements.) The `freedata(dname)` routine frees memory associated with the named data file, or all data arrays if `dname` is `NULL`.
489    
490     The routine that interpolates data values is `datavalue(dp,pt)`, which takes a `DATARRAY` pointer and an array of **double**s of the appropriate length (the number of dimensions in `dp`). The **double** returned is the interpolated value at that point in the scalar field. If the requested point lies outside the data's grid, it is extrapolated from the perimeter values up to a distance of one division in each dimension, and falls off harmonically to zero outside of that. This was selected as the most robust compromise, but to be safe it is generally best to avoid giving out-of-domain points to `datavalue`.
491    
492     ## Font File Format (.fnt suffix)
493     Font files are used for text patterns and mixtures, and by the **psign** program to generate simple text labels. Each character glyph is set up on a simple rectangular coordinate system running from [0,255] in x and y, and the glyph itself is a polygon. Figure 2 shows an example of the letter "A".
494    
495     ![Drawing of an A, based on coordinates](figure2.svg)
496    
497     **Figure 2.** A glyph for an "A" character in standard font coordinates. Note that the hole is made via a seam, just as with *Radiance* scene polygons. The actual aspect and spacing of the character will be determined by the client program.
498    
499     Each glyph begins with the decimal value of that character's index, which is 65 for "A" according to the ASCII standard. This is followed by the number of vertices, then the vertices themselves in $(x_1, y_1), (x_2, y_2)$ order. White space again serves as a separator, and comments may begin with a pound sign ('#') and continue to the end of line. Here is the glyph entry for the letter "A" corresponding to Figure 2:
500    
501     65 15 # Helvetica "A"
502     155 222 242 48 185 48 168 86
503     83 86 65 48 12 48 101 222
504     155 222 128 179 126 179 97 116
505     155 116 128 179 155 222
506    
507     If the number of vertices given is zero, then the character is a space. This is not the same as no entry, which means there is no valid glyph for that character. Glyphs may appear in any order, with indices ranging from 0 to 255. The maximum number of vertices for a single glyph is 32767.
508    
509     Two standard font files are provided, `helvet.fnt` and `hexbit4x1.fnt`. The former is a Helvetica font from the public domain Hershey font set. The second is a simple bit pattern font for hexadecimal encodings of bitmaps.
510    
511     ### *Radiance* Programs
512     Table 4 shows *Radiance* programs that read and write font files.
513    
514     Program | Read | Write | Function
515     ----------- | ---- | ----- | --------
516     **pcompos** | X || Compose *Radiance* pictures
517     **psign** | X || Generate *Radiance* picture label
518     **rpict** | X || Batch rendering program
519     **rtrace** | X || Customizable ray-tracer
520     **rview** | X || Interactive renderer
521    
522     **Table 4.** Programs in the *Radiance* distribution that read and write font files.
523    
524     ### *Radiance* C Library
525     Similar to data files, font files are usually read and stored in a lookup table. The data structures for fonts are in src/common/font.h, and the routines for reading and spacing them are in `src/common/font.c`. The main structure type is `FONT`. The routine `getfont(fname)` loads a font file from the *Radiance* library (set by the `RAYPATH` environment variable), and returns a pointer to the resulting `FONT` structure. If the file has been previously loaded, a pointer to the stored structure is returned. The `freefont(fname)` routine frees memory associated with the named font file and deletes it from the table, or frees all font data if `fname` is `NULL`.
526    
527     Three different routines are available for text spacing. The `uniftext(sp,tp,f`) function takes the nul-terminated string `tp` and computes uniform per-character spacing for the font `f`, returned in the short integer array `sp`. (This is a fairly simple process, and all spacing values will be 255 unless a character has no corresponding glyph.) The `squeeztext(sp,tp,f,cis)` performs a similar function, but puts only `ci`s units between adjacent characters, based on the actual width of each font glyph. The most sophisticated spacing function is `proptext(sp,tp,f,cis,nsi)`, which produces a total line length equal to what it would be with uniform spacing, while maintaining equal inter-character spacing throughout (i.e., proportional spacing). The `nsi` argument is the number of spaces (zero-vertex glyphs) considered as an indent. That is, if this many or more adjacent spaces occur in `tp`, the indented text following will appear at the same point as it would have had the spacing been uniform. This maintains columns in tabulated text despite the proportional spacing. Tabs are not understood or interpreted by any of these routines, and must be expanded to the appropriate number of spaces via **expand**.
528    
529     ### Octree Format (.oct suffix)
530     In *Radiance*, octrees are used to accelerate ray intersection calculations as described by Glassner [Glassner84]. This data structure is computed by the **oconv** program, which produces a binary file as its output. An octree file contains a list of *Radiance* scene description files (which may be empty), some information to guarantee portability between systems and different versions of the code, followed by the octree data itself. If the octree file is "frozen," then it will also contain the scene data, compiled into a binary format for quick loading. This is most convenient for octrees that are used in *instance* primitives, which may be moved to a different (library) location from the originating scene files.
531    
532     An octree recursively subdivides 3-dimensional space into 8 subtrees, hence its name. Each "leaf" node contains between zero and `MAXSET` surface primitives, indicating that section of space contains part or all of those surfaces. (Surface primitives may appear more than once in the octree.) The goal of **oconv** is to build an octree that contains no more than N surfaces in each leaf node, where N is set by the **-n** option (5 by default). It may allow more surfaces in places where the octree has reached its maximum resolution (depth), set by the **-r** option (1024 — depth 10 by default). Figure 3 shows a quadtree dividing 2-dimensional space, analogous to our 3-dimensional octree.
533    
534     ![A quadtree dividing two-dimensional space](figure3.svg)
535    
536     **Figure 3.** An example quadtree divided so that no leaf node contains more than 2 objects. A three-dimensional octree works the same way. Each leaf node is either empty, or contains a list of intersecting surfaces.
537    
538     ### Basic File Structure
539     An octree file is divided into five sections: the information header, the scene boundaries, the scene file names, the octree data structure, and the compiled scene data. If the octree is frozen, then the compiled scene data is included and the scene file names are not. Otherwise, the scene data is left off.
540    
541     #### Information Header
542     As with other binary *Radiance* formats, the beginning of an octree file is the information header. The first line is "#?RADIANCE" to aid in identification by the UNIX **file** program. Following this is the **oconv** command (or commands) used to produce the octree, then a line indicating the format, `FORMAT=Radiance_octree`. The end of the information header is always an empty line. Here is an example of an octree information header, as reported by **getinfo**:
543    
544     #?RADIANCE
545     oconv model.b90 desk misc
546     oconv -f -i modelb.oct window blinds lights lamp
547     FORMAT=Radiance_octree
548    
549     The actual content of this header is ignored when an octree is read except for the `FORMAT` line, which if it appears must match the one shown above.
550    
551     #### Scene Boundaries
552     After the information header, there is a magic number indicating the format version and the size of object indices (in bytes per index). This is a two-byte quantity, which must be one of the following in the current release:
553    
554     | | |
555     |---|---|
556     285 | Two-byte object indices.
557     287 | Four-byte object indices.
558     291 | Eight-byte object indices. (Only supported on architectures with 64-bit **longs**.)
559    
560     Technically, the code will also support odd-sized integers, but they are not found on any existing machine architectures so we can forget about them.
561    
562     Following the octree magic number, we have the enclosing cube for the scene, which defines the dimensions of the octree's root node. The cube is aligned along the world coordinate axes, so may be defined by one corner (the 3-dimensional minimum) and the side length. For historical reasons, these four values are stored as ASCII-encoded real values in nul-terminated strings. (The octree boundaries may also be read using **getinfo** with the **-d** option.)
563    
564     #### Scene File Names
565     Following the octree dimensions, the names of the scene description files are given, each stored a nul-terminated string. The end of this file list is indicated by an empty string. If the octree is "frozen," meaning it contains the compiled scene information as well, then no file names will be present (i.e., the first string will be empty).
566    
567     #### Octree Data Structure
568     After the scene description files, an N-byte integer indicates the total number of primitives given to **oconv**, where N is the size derived from the magic number as we described. This object count will be used to verify that the files have not changed significantly since the octree was written[^5].
569    
570     [^5]: Small changes that do not affect geometry will not cause problems, but if the primitive count changes, so does the indexing of surfaces, and with that the octree data structure becomes invalid. A second check is made to insure that no non-surface primitives appear in any leaf nodes, and this at least guarantees that the renderer will not dump core from an outdated octree, even if the results are wrong.
571    
572     After the primitive count, the actual octree is stored, using the following recursive procedure:
573    
574     puttree(ot) begin
575     if ot is a tree then
576     write the character '\002'
577     call puttree on each child node (0-7) else if ot is empty then
578     write the character '\000'
579     else
580     write the character '\001'
581     write out the number of surfaces
582     write out each surface's index
583     end
584     end puttree
585    
586     The number of surfaces and the surface indices are each N-byte integers, and the tree node types are single bytes. Reading the octree is accomplished with a complementary procedure.
587    
588     #### Compiled Scene Data
589     If the octree is frozen, then this data structure is followed by a compiled version of the scene. This avoids the problems of changes to scene files, and allows an octree to be moved conveniently from one location and one system to another without worrying about the associated scene files.
590    
591     The scene data begins with a listing of the defined primitive types. This list consists of the name of each type as a nul-terminated string, followed by an empty string once the list has been exhausted. This permits the indexing of primitive types with a single byte later on, without concern about changes to *Radiance* involving `src/common/otypes.h`.
592    
593     The scene primitives are written one at a time. First is a single byte with the primitive type index, as determined from the list given above. Second is the N-byte modifier index, followed by the primitive's identifier as a nul-terminated string. String arguments start with a 2-byte integer indicating the argument count, followed by the strings themselves, which are nul-terminated. Real arguments next have a 2-byte count followed by the real values, each stored as a 4-byte mantissa followed by a 1-byte (signed) exponent. (The mantissa is the numerator of a fraction of $2^{31} - 1$.) The end of data is indicated with a -1 value for the object type (byte=255).
594    
595     ### *Radiance* Programs
596     Table 5 shows *Radiance* programs that read and write octree files.
597    
598     Program | Read | Write | Function
599     --------|------|-------|---------
600     **getinfo** | X | | Print information header from binary file
601     **oconv** | X | X | Compile *Radiance* scene description
602     **rad** | X | X | Render *Radiance* scene
603     **rpict** | X | | Batch rendering program
604     **rpiece** | X | | Parallel batch rendering program
605     **rtrace** | X | | Customizable ray-tracer
606     **rview** | X | | Interactive renderer
607    
608     **Table 5.** Programs in the *Radiance* distribution that read and write octree files.
609    
610     ### *Radiance* C Library
611     Since reading an octree file also may involve reading a *Radiance* scene description, some of the same library routines are called indirectly. The header file `src/common/octree.h` is needed in addition to the `src/common/object.`h file. The module `src/ot/writeoct.c` contains the main routines for writing an octree to stdout, while `src/common/readoct.c` contains the corresponding routines for reading an octree from a file. Both modules access routines in `src/common/portio.c` for reading and writing portable binary data.
612    
613     Here is the main call for writing out an octree:
614    
615     `writeoct(int store, CUBE *scene, char *ofn[]);`
616     : Write the octree stored in scene to stdout, assuming the header has already been written. The flags in store determine what will be included. Normally, this variable is one of `IO_ALL` or `(IO_ALL & ~IO_FILES)` correspondingto writing a normal or a frozen octree, respectively.
617    
618     Here is the main call for reading in an octree:
619    
620     `readoct(char *fname, int load, CUBE *scene, char *ofn[]);`
621     : Read the octree file fname into scene, saving scene file names in the ofn array. What is loaded depends on the flags in load,which may be one or more of `IO_CHECK`, `IO_INFO`, `IO_SCENE`, `IO_TREE`, `IO_FILES` and `IO_BOUNDS`. These correspond to checking file type and consistency, transferring the information header to stdout, loading the scene data, loading the octree structure, assigning the scene file names to ofn, and assigning the octree cube boundaries. The macro `IO_ALL` includes all of these flags, for convenience.
622    
623     ## Picture File Format (.hdr suffix)
624     *Radiance* pictures[^pic] differ from standard computer graphics images inasmuch as they contain real physical data, namely radiance values at each pixel. To do this, it is necessary to maintain floating point information, and we use a 4-byte/pixel encoding described in Chapter II.5 of Graphics Gems II [Arvo91,p.80]. The basic idea is to store a 1-byte mantissa for each of three primaries, and a common 1-byte exponent. The accuracy of these values will be on the order of 1% (±1 in 200) over a dynamic range from 10^-38^ to 10^38^.
625    
626     [^pic]: The picture filename extension used to be .pic, but that conflicted with too many other programs. It was replaced with .hdr, an abbreviation of "high dynamic range."
627    
628     Although *Radiance* pictures *may* contain physical data, they do not *necessarily* contain physical data. If the rendering did not use properly modeled light sources, or the picture was converted from some other format, or custom filtering was applied, then the physical data will be invalid. Table 6 lists programs that read and write *Radiance* pictures, with pluses next to the X-marks indicating where physical data is preserved (or at least understood). Specifically, if the picture file read or written by a program has an "X+", then it has maintained the physical validity of the pixels by keeping track of any exposure or color corrections in the appropriate header variables, described below.
629    
630     ### Basic File Structure
631     *Radiance* picture files are divided into three sections: the information header, the resolution string, and the scanline records. All of these must be present or the file is incomplete.
632    
633     #### Information Header
634     The information header begins with the usual `#?RADIANCE` identifier, followed by one or more lines containing the programs used to produce the picture. These commands may be interspersed with variables describing relevant information such as the view, exposure, color correction, and so on. Variable assignments begin on a new line, and the variable name (usually all upper case) is followed by an equals sign ('='), which is followed by the assigned value up until the end of line. Some variable assignments override previous assignments in the same header, where other assignments are cumulative. Here are the most important variables for *Radiance* pictures:
635    
636     `FORMAT`
637     : A line indicating the file's format. At most one `FORMAT` line is allowed, and it must be assigned a value of either `32- bit_rle_rgbe` or `32-bit_rle_xyze` to be a valid *Radiance* picture.
638    
639     `EXPOSURE`
640     : A single floating point number indicating a multiplier that has been applied to all the pixels in the file. `EXPOSURE` values are cumulative, so the original pixel values (i.e., radiances in w/sr/m^2^) must be derived by taking the values in the file and dividing by all the `EXPOSURE` settings multiplied together. No `EXPOSURE` setting implies that no exposure changes have taken place.
641    
642     `COLORCORR`
643     : A color correction multiplier that has been applied to this picture. Similar to the `EXPOSURE` variable except given in three parts for the three primaries. In general, the value should have a brightness of unity, so that it does not affect the actual brightness of pixels, which should be tracked by `EXPOSURE` changes instead. (This variable is also cumulative.)
644    
645     `SOFTWARE`
646     : The software version used to create the picture, usually something like `RADIANCE 3.04 official release July 16, 1996`.
647    
648     `PIXASPECT`
649     : The pixel aspect ratio, expressed as a decimal fraction of the height of each pixel to its width. This is not to be confused with the image aspect ratio, which is the total height over width. (The image aspect ratio is actually equal to the height in pixels over the width in pixels, *multiplied* by the pixel aspect ratio.) These assignments are cumulative, so the actual pixel aspect ratio is all ratios multiplied together. If no `PIXASPECT` assignment appears, the ratio is assumed to be 1.
650    
651     `VIEW`
652     : The *Radiance* view parameters used to create this picture. Multiple assignments are cumulative inasmuch as new view options add to or override old ones.
653    
654     `PRIMARIES`
655     The CIE (x,y) chromaticity coordinates of the three (RGB) primaries and the white point used to standardize the picture's color system. This is used mainly by the **ra_xyze** program to convert between color systems. If no `PRIMARIES` line appears, we assume the standard primaries defined in `src/common/color.h`, namely `0.640 0.330 0.290 0.600 0.150 0.060 0.333 0.333` for red, green, blue and white, respectively.
656    
657     As always, the end of the header is indicated by an empty line.
658    
659     #### Resolution String
660     All *Radiance* pictures have a standard coordinate system, which is shown in Figure 4. The origin is always at the lower left corner, with the X coordinate increasing to the right, and the Y coordinate increasing in the upward direction. The actual ordering of pixels in the picture file, however, is addressed by the resolution string.
661    
662     ![Radiance picture coordinate system](figure4.svg)
663    
664     **Figure 4.** The standard coordinate system for an MxN picture.
665    
666     The resolution string is given as one of the following:
667    
668     `-Y N +X M`
669     : The standard orientation produced by the renderers, indicating that Y is decreasing in the file, and X is increasing. X positions are increasing in each scanline, starting with the upper left position in the picture and moving to the upper right initially, then on down the picture. Some programs will only handle pictures with this ordering.
670    
671     `-Y N -X M`
672     : The X ordering has been reversed, effectively flipping the image
673     left to right from the standard ordering.
674    
675     `+Y N -X M`
676     : The image has been flipped left to right and also top to bottom, which is the same as rotating it by 180 degrees.
677    
678     `+Y N +X M`
679     : The image has been flipped top to bottom from the standard
680     ordering.
681    
682     `+X M +Y N`
683     : The image has been rotated 90 degrees clockwise.
684    
685     `-X M +Y N`
686     : The image has been rotated 90 degrees clockwise, then flipped
687     top to bottom.
688    
689     `-X M -Y N`
690     : The image has been rotated 90 degrees counter-clockwise.
691    
692     `+X M -Y N`
693     : The image has been rotate 90 degrees counter-clockwise, then flipped top to bottom.
694    
695     The reason for tracking all these changes in picture orientation is so programs that compute ray origin and direction from the `VIEW` variable in the information header will work despite such changes. Also, it can reduce memory requirements on converting from other image formats that have a different scanline ordering, such as Targa.
696    
697     #### Scanline Records
698     *Radiance* scanlines come in one of three flavors, described below:
699    
700     Uncompressed
701     : Each scanline is represented by M pixels with 4 bytes per pixel, for a total length of 4xM bytes. This is the simplest format to read and write, since it has a one-to-one correspondence to an array of `COLR` values.
702    
703     Old run-length encoded
704     : Repeated pixel values are indicated by an illegal (i.e., unnormalized) pixel that has 1's for all three mantissas, and an exponent that corresponds to the number of times the previous pixel is repeated. Consecutive repeat indicators contain higher-order bytes of the count.
705    
706     New run-length encoded
707     : In this format, the four scanline components (three primaries and exponent) are separated for better compression using adaptive run-length encoding (described by Glassner in Chapter II.8 of Graphics Gems II [Arvo91,p.89]). The record begins with an unnormalized pixel having two bytes equal to 2, followed by the upper byte and the lower byte of the scanline length (which must be less than 32768). A run is indicated by a byte with its high-order bit set, corresponding to a count with excess 128. A non-run is indicated with a byte less than 128. The maximum compression ratio using this scheme is better than 100:1, but typical performance for *Radiance* pictures is more like 2:1.
708    
709     The physical values these scanlines correspond to depend on the format and other information contained in the information header. If the `FORMAT` string indicates RGB data, then the units for each primary are spectral radiances over the corresponding waveband, such that a pixel value of $(1,1,1)$ corresponds to a total energy of 1 w/sr/m^2^ over the visible spectrum. The actual luminance value (in lm/sr/m^2^) can be computed from the following formula for the standard *Radiance* RGB primaries:
710    
711     $$L_v = 179(0.265r + 0.670g + 0.065b)$$
712    
713     The value of 179 lm/w is the standard *luminous efficacy* of equal-energy white light that is defined and used by *Radiance* specifically for this conversion. This and the other values above are defined in `src/common/color.h`, and the above formula is given as a macro, `luminance(col)`.
714    
715     If the `FORMAT` string indicates XYZ data, then the units of the Y primary are already lm/st/m^2^, so the above conversion is unnecessary.
716    
717     ### *Radiance* programs
718     Table 6 shows the many programs that read and write *Radiance* pictures.
719    
720     Program | Read | Write | Function
721     ----------------|------|-------|---------
722     **falsecolor** | X+ | X | Create false color image
723     **findglare** | X+ | | Find sources of discomfort glare
724     **getinfo** | X | | Print information header from binary file
725     **macbethcal** | X | X | Compute image color & contrast correction
726     **normpat** | X | X | Normalize picture for use as pattern tile
727     **objpict** | | X | Generate composite picture of object
728     **pcomb** | X+ | X | Perform arbitrary math on picture(s)
729     **pcond** | X+ | X | Condition a picture for display
730     **pcompos** | X | X | Composite pictures
731     **pextrem** | X+ | | Find minimum and maximum pixels
732     **pfilt** | X+ | X+ | Filter and anti-alias picture
733     **pflip** | X+ | X+ | Flip picture left-right and/or top-bottom
734     **pinterp** | X+ | X+ | Interpolate/extrapolate picture views
735     **protate** | X+ | X+ | Rotate picture 90 degrees clockwise
736     **psign** | | X | Create text picture
737     **pvalue** | X+ | X+ | Convert picture to/from simpler formats
738     **ra_avs** | X | X | Convert to/from AVS image format
739     **ra_pict** | X | X | Convert to/from Macintosh PICT2 format
740     **ra_ppm** | X | X | Convert to/from Poskanzer Port. Pixmap
741     **ra_pr** | X | X | Convert to/from Sun 8-bit rasterfile
742     **ra_pr24** | X | X | Convert to/from Sun 24-bit rasterfile
743     **ra_ps** | X | | Convert to B&W or color PostScript
744     **ra_rgbe** | X | X | Convert to/from uncompressed picture
745     **ra_t8** | X | X | Convert to/from Targa 8-bit format
746     **ra_t16** | X | X | Convert to/from Targa 16-bit and 24-bit
747     **ra_tiff** | X | X | Convert to/from TIFF 8-bit and 24-bit
748     **ra_xyze** | X | X | Convert to/from CIE primary picture
749     **rad** | | X+ | Render Radiance scene
750     **ranimate** | | X+ | Animate Radiance scene
751     **rpict** | X | X+ | Batch rendering program
752     **rpiece** | X | X+ | Parallel batch rendering program
753     **rtrace** | X | X+ | Customizable ray-tracer
754     **rview** | X | X+ | Interactive renderer
755     **vwright** | X | | Get view parameters and shift them
756     **xglaresrc** | X | | Display glare sources from **findglare**
757     **ximage** | X+ | | Display *Radiance* picture under *X11*
758     **xshowtrace** | X | | Show ray traces on *X11* display
759    
760     **Table 6.** *Radiance* programs that read and write picture files. Pluses indicate when a program makes use of or preserves physical pixel values.
761    
762     ### *Radiance* C Library
763     There are a fair number of routines for reading, writing and manipulating *Radiance* pictures. If you want to write a converter to or from a 24-bit image format, you can follow the skeletal example in `src/px/ra_skel.c`. This has all of the basic functionality of the other **ra_\*** image conversion programs, with the actual code for the destination type removed (or simplified). The method in `ra_skel` uses the routines in `src/common/colrops.c` to avoid conversion to machine floating point, which can slow things down and is not necessary in this case.
764    
765     Below we describe routines for reading and writing pictures, which rely heavily on definitions in `src/common/color.h`. We start with the calls for manipulating information headers, followed by the calls for resolution strings, then the calls for scanline records.
766    
767     Information headers are manipulated with the routines in `src/common/header.c` and the macros in `color.h`. Features for handing views are defined in `src/common/view.h` with routines in `src/common/image.c`. Here are the relevant calls for reading and copying information headers:
768    
769     `int checkheader(FILE *fin, char *fmt, FILE *fout);`
770     : Read the header information from `fin`, copying to `fou`t (unless fout is `NULL`), checking any `FORMAT` line against the string `fmt`. The `FORMAT` line (if it exists) will not be copied to `fout`. The function returns 1 if the header was OK and the format matched, 0 if the header was OK but there was no format line, and -1 if the format line did not match or there was some problem reading the header. Wildcard characters ('\*' and '?') may appear in `fmt`, in which case a globbing match is applied, and the matching format value will be copied to fmt upon success. The normal `fmt` values for pictures are `COLRFMT` for *Radiance* RGB, `CIEFMT` for 4-byte XYZ pixels, or a copy of `PICFMT` for glob matches to either. (Do not pass `PICFMT` directly, as this will cause an illegal memory access on systems that store static strings in read-only memory.)
771    
772     `int getheader(FILE *fp, int (*f)(), char *p);`
773     : For those who need more control, `getheader` reads the header from `fp`, calling the function `f` (if not` NULL`) with each input line and the client data pointer `p`. A simple call to skip the header is `getheader(fp,NULL,NULL)`. To copy the header unconditionally to `stdout`, call `getheader(fp,fputs,stdout)`. More often, `getheader` is called with a client function, which checks each line for specific variable settings.
774    
775     `int isformat(char *s);`
776     : Returns non-zero if the line `s` is a `FORMAT` assignment.
777    
778     `int formatval(char *r, char *s);`
779     : Returns the `FORMAT` value from line `s` in the string `r`. Returns
780     non-zero if `s` is a valid format line.
781    
782     `fputformat(char *s, FILE *fp);`
783     : Put format assignment `s` to the stream `fp`.
784    
785     `isexpos(s)`
786     : Macro returns non-zero if the line `s` is an `EXPOSURE` setting.
787    
788     exposval(s)
789     : Macro returns **double** exposure value from line `s`.
790    
791     `fputexpos(ex,fp)`
792     : Macro** | puts real exposure value `ex` to stream `fp`.
793    
794     `iscolcor(s)`
795     :Macro returns non-zero if the line `s` is a `COLORCORR` setting.
796    
797     `colcorval(cc,s)`
798     : Macro assign color correction value from line `s` in the `COLOR`
799     variable `cc`.
800    
801     `fputcolcor(cc,fp)`
802     : Macro puts correction `COLOR` `cc` to stream `fp`.
803    
804     `isaspect(s)`
805     : Macro returns non-zero if the line `s` is a `PIXASPECT` setting.
806    
807     `aspectval(s)`
808     : Macro returns double pixel aspect value from line `s`.
809    
810     `fputaspect(pa,fp)`
811     : Macro puts real pixel aspect value `pa` to stream `fp`.
812    
813     `int isview(char *s);`
814     : Returns non-zero if header line `s` contains view parameters. Note that ``s` could be either a `VIEW` assignment or a rendering command.
815    
816     `int sscanview(VIEW *vp, char *s);`
817     : Scan view options from the string `s` into the `VIEW` structure
818     pointed to by `vp`.
819    
820     `fprintview(VIEW *vp, FILE *fp);`
821     : Print view options in `vp` to the stream `fp`. Note that this does not print out "VIEW=" first, or end the line. Therefore, one usually calls `fputs(VIEWSTR,fp)` followed by `fprintview(vp,fp)`, then `putc('\n',fp)`.
822    
823     `isprims(s)`
824     : Macro returns non-zero if the line `s` is a `PRIMARIES` setting.
825    
826     `primsval(p,s)`
827     : Macro assign color primitives from line `s` in the `RGBPRIMS`
828     variable `p`.
829    
830     `fputprims(p,fp)`
831     : Macro puts color primitives `p` to stream `fp`.
832    
833     The header file `src/common/resolu.h` has macros for resolution strings, which are handled by routines in `src/common/resolu.c`. Here are the relevant calls:
834    
835     `fgetsresolu(rs,fp)`
836     : Macro to get a resolution string from the stream `fp` and put it in the `RESOLU` structure pointed to by `rs`. The return value is non-zero if the resolution was successfully loaded.
837    
838     `fputsresolu(rs,fp)`
839     : Macro to write the `RESOLU` structure pointed to by rs to the
840     stream fp.
841    
842     `scanlen(rs)`
843     : Macro to get the scanline length from the `RESOL`U structure
844     pointed to by `rs`.
845    
846     `numscans(rs)`
847     : Macro to get the number of scanlines from the `RESOLU`
848     structure pointed to by `rs`.
849    
850     `fscnresolu(slp,nsp,fp)`
851     : Macro to read in a resolution string from `f`p and assign the scanline length and number of scanlines to the integers pointed to by `slp` and `nsp`, respectively. This call expects standard English-text ordered scanlines, and returns non-zero only if the resolution string agrees.
852    
853     `fprtresolu(sl,ns,fp)`
854     : Macro to print out a resolution string for `ns` scanlines of length `sl` in standard English-text ordering to `fp`.
855    
856     The file `src/common/color.c` contains the essential routines for reading and writing scanline records. Here are the relevant calls and macros:
857    
858     `int freadcolrs(COLR *scn, int sl, FILE *fp);`
859     : Read a scanline record of length `sl` from stream `fp` into the `COLR` array `scn`. Interprets uncompressed, old, and new run-length encoded records. Returns 0 on success, -1 on failure.
860    
861     `int fwritecolrs(COLR *scn, int sl, FILE *fp);`
862     : Write the scanline record stored in the `COLR` array `scn`, length `sl`, to the stream `fp`. Uses the new run-length encoding unless `sl` is less than 8 or greater than 32767, when an uncompressed record is written. Returns 0 on success, -1 if there was an error.
863    
864     `int freadscan(COLOR *fscn, int sl, FILE *fp);`
865     : Reads a scanline of length `sl` from the stream `fp` and converts to machine floating-point format in the array `fscn`. Recognizes all scanline record encodings. Returns 0 on success, or -1 on failure.
866    
867     `int fwritescan(COLOR *fscn, int sl, FILE *fp);`
868     : Write the floating-point scanline of length `sl` stored in the array fscn to the stream `fp`. Converts to 4-byte/pixel scanline format and calls `fwritecolrs` to do the actual write. Returns 0 on success, or -1 if there was an error.
869    
870     `colval(col,p)`
871     : Macro to get primary p from the floating-point `COLOR col`. The primary index may be one of `RED`, `GRN` or `BLU` for RGB colors, or CIEX, CIEY or CIEZ for XYZ colors. This macro is a valid lvalue, so can be used on the left of assignment statements as well.
872    
873     `colrval(clr,p)`
874     : Macro to get primary `p` from the 4-byte `COLR` pixel `clr`. The primary index may be one of RED, GRN or BLU for RGB colors, or CIEX, CIEY or CIEZ for XYZ colors. Unless just one primary is needed, it is more efficient to call `colr_color` and use the `colval` macro on the result.
875    
876     `colr_color(COLOR col, COLR clr);`
877     : Convert the 4-byte pixel `clr` to a machine floating-point
878     representation and store the result in `col`.
879    
880     `setcolr(COLR clr, double p1, p2, p3);`
881     : Assign the 4-byte pixel `clr` according to the three primary values `p1`, `p2` and `p3`. These can be either *Radiance* RGB values or CIE XYZ values.
882    
883     ## Z-buffer Format (.zbf suffix)
884     The Z-buffer format used in *Radiance* hardly qualifies as a format at all. It is in fact a straight copy on the 4-byte machine floating point values of each pixel in standard scanline order. There is no information header or resolution string that would make the file independently useful. This is usually OK, because Z-buffer files are almost always created and used in conjunction with a picture file, which has this identifying information.
885    
886     The major shortcoming of this format is that the machine representation and byte ordering is not always the same from one system to another, which limits the portability of Z-buffer files. Since they are primarily used for interpolating animation frames, and this usually occurs on networks with similar architectures, there is usually no problem. Also, since the adoption of IEEE standard floating-point calculations, different machine representations are becoming quite rare. [TBD: is this necessary at this point?]
887    
888     ### *Radiance* programs
889     Table 7 shows the programs that read and write *Radiance* Z-buffer files. The pvalue program may be used to convert Z-buffer files to *Radiance* pictures for the purpose of visualizing the values using falsecolor. For example, the following command converts the Z-buffer file `frame110.zbf` associated with the picture `frame110.hdr` to a viewable image:
890    
891     % pvalue -h `getinfo -d < frame110.hdr` -r -b -df
892     frame110.zbf | falsecolor -m 1 -s 40 -l Meters >
893     frame110z.hdr
894    
895     The **getinfo** program appearing in back-quotes was used to get the dimensions associated with the Z-buffer from its corresponding picture file.
896    
897     Program | Read | Write | Function
898     --------|------|-------|---------
899     **pinterp** | X | X | Interpolate/extrapolate picture views
900     **pvalue** | X | X | Convert picture to/from simpler formats
901     **rad** | | X | Render Radiance scene
902     **ranimate** | X | X | Animate Radiance scene
903     **rpict** | | X | Batch rendering program
904     **rtrace** | | X | Customizable ray-tracer
905    
906     **Table 7.** *Radiance* programs that read and write Z-buffer files.
907    
908     ### *Radiance* C Library
909     There are no library functions devoted to reading and writing Z-buffer files in particular. The normal method is to read and write Z-buffer scanlines with the standard `fread` and `fwrite` library functions using an appropriate float array.
910    
911     ## Ambient File Format (.amb suffix)
912     *Radiance* can store its diffuse interreflection cache in an *ambient file* for reuse by other processes. This file is in a system-independent binary format, similar to an octree or picture file, with an information header that can be read using **getinfo**. Following the header, there is a magic number specific to this file type, then the ambient value records themselves in encoded form.
913    
914     #### Information Header
915    
916     The information header begins with the usual "#?RADIANCE" identifier, followed by the originating program and the ambient calculation parameters (and octree name). After this is the line:
917    
918     FORMAT=Radiance_ambval
919    
920     This identifies the general file type, followed by an empty line ending the header. As with most information headers, this exact sequence need not be followed, so long as there is no inconsistent `FORMAT` setting.
921    
922     #### Magic Number
923     Following the information header is the two-byte magic number, which for the current ambient file format is 557. This number may change later should the file format be altered in incompatible ways.
924    
925     #### Ambient Value Records
926     Ambient values are written to the file in no particular order. Each diffuse interreflection value in *Radiance* has the following members:
927    
928     Level
929     : The number of reflections between the primary (eye) ray and this surface. A value with fewer reflections may be used in place of one with more, but not the other way around.
930    
931     Weight
932     : The weighting value associated with this ray or ambient value. Similar to the level to avoid using inappropriate values from the cache.
933    
934     Position
935     : The origin point of this interreflection calculation.
936    
937     Direction
938     : The surface normal indicating the zenith of the sample hemisphere for this value.
939    
940     Value
941     : The calculated indirect irradiance at this point, in w/m^2^ (RGB color).
942    
943     Radius
944     : The cosine-weighted, harmonic mean distance to other surfaces visible from this point, used to decide point spacing.
945    
946     Posgradient
947     : The position-based gradient vector, indicating how brightness changes as a function of position in the sample plane.
948    
949     Dirgradient
950     : The direction-based gradient vector, indicating how brightness changes as a function of surface orientation.
951    
952     The members are stored one after the other in the above order using system-independent binary representations. The Level member takes 1 byte, Weight takes 5, Position takes 15, Direction another 15, Value is 4 bytes (using the same color format as *Radiance* pictures), Radius takes 5 bytes, and Posgradient and Dirgradient each take 15 bytes, for a total size of 75 bytes per record.
953    
954     ### *Radiance* Programs
955     Table 8 shows *Radiance* programs that read and write ambient files. The program **lookamb** is especially useful for examining the contents of ambient files and debugging problems in the calculation.
956    
957     Program | Read | Write | Function
958     -------------|------|-------|---------
959     **getinfo** | X | | Print information header from binary file
960     **lookamb** | X | X | Convert *Radiance* ambient file
961     **rad** | X | X | Render *Radiance* scene
962     **rpict** | X | X | Batch rendering program
963     **rpiece** | X | X | Parallel batch rendering program
964     **rtrace** | X | X | Customizable ray-tracer
965     **rview** | X | X | Interactive renderer
966    
967     **Table 8.** Programs in the *Radiance* distribution that read and write ambient files.
968    
969     ### *Radiance* C Library
970     The `src/rt/ambient.h` file contains definitions of the `AMBVAL` structure and certain details of the ambient file format. The `src/rt/ambio.c` module contains the specialized routines for reading and writing ambient files, and these functions in turn access routines in `src/common/portio.c` for reading and writing portable binary data. The information header is handled by the routines in s`rc/common/header.c`, similar to the method described for *Radiance* picture files. Here are the main calls from `src/rt/ambio.c`:
971    
972     `putambmagic(FILE *fp);`
973     : Put out the appropriate two-byte magic number for a *Radiance* ambient file to the stream `fp`.
974    
975     `int hasambmagic(FILE *fp);`
976     : Read the next two bytes from the stream `fp` and return non-zero
977     if they match an ambient file's magic number.
978    
979     `int writeambval(AMBVAL *av, FILE *fp);`
980     : Write out the ambient value structure `av` to the stream `fp`, returning -1 if a file error occurred, or 0 normally.
981    
982     `int readambval(AMBVAL *av, FILE *fp);`
983     : Read in the next ambient value structure from the stream `fp` and put the result in `av`. Return 1 if the read was successful, 0 if the end of file was reached or there was an error. The `ambvalOK` function is used to check the consistency of the value read.
984    
985     `int ambvalOK(AMBVAL *av);`
986     : Return non-zero if the member values of the `av` structure are not too outlandish. This is handy as insurance against a corrupted ambient file.
987    
988     ## Conclusion
989     We have described the main file formats native to *Radiance* and shown how even the binary formats can be reliably shared in heterogeneous computing environments. This corresponds to one of the basic philosophies of UNIX software, which is system independence. A more detailed understanding of the formats may still require some use of binary dump programs and delving into the *Radiance* source code.