ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/doc/filefmts.md
Revision: 1.3
Committed: Thu Nov 24 02:01:39 2022 UTC (17 months, 2 weeks ago) by greg
Branch: MAIN
CVS Tags: rad5R4, HEAD
Changes since 1.2: +12 -12 lines
Log Message:
docs(filefmts): updates and additions from Randolph Fritz

File Contents

# Content
1 # RCSid $Id: filefmts.md,v 1.2 2022/11/11 02:38:34 greg Exp $
2 # *Radiance* File Formats
3 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:
4
5 Scene Description (.rad suffix)
6 : 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.
7
8 Function File (.cal suffix)
9 : 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.
10
11 Data File (.dat suffix)
12 : Another ASCII format, data files are used directly by the rendering programs to interpolate values for luminaire photometry, among other things.
13
14 Font File (.fnt suffix)
15 : 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.
16
17 Octree (.oct suffix)
18 : 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.
19
20 Picture (.hdr suffix)
21 : A binary image file containing calibrated, real radiance values at each pixel. *Radiance* pictures may be displayed, analyzed, and converted to other image formats.
22
23 Z-buffer (.zbf suffix)
24 : A binary file with the distances to each pixel in a corresponding picture.
25
26 Ambient File (.amb suffix)
27 : 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.
28
29 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.
30
31 [^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.
32
33 ## Scene Description Format (.rad suffix)
34 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.
35
36 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.
37
38 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.
39
40 ### Basic File Structure
41 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.
42
43 #### Comments
44 The simplest statement type is a comment statement begins with a pound sign ('#') and continues to the end of line:
45
46 # This is a comment.
47
48 #### Commands
49 An in-line command, which begins with an exclamation mark ('!') and continues to the end of line:
50
51 !xform -n chair1 -t 10 5 8 chair.rad
52
53 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 ('\\'):
54
55 !gensurf marble sink '15.5+x(theta(s),phi(t))' \
56 '10.5+y(theta(s),phi(t))' \
57 '30.75+z(theta(s),phi(t))' \
58 8 29 -f basin.cal -s
59
60 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:
61
62 !( echo marble polygon sink_top 0 0 108 31 \
63 10.5 30.75 31 22 30.75 0 22 30.75 0 0 \
64 30.75 31 0 30.75 31 10.5 30.75 ; \
65 cnt 30 | rcalc \
66 -e '$1=15.5+x(theta(0),phi(1-$1/29))' \
67 -e '$2=10.5+y(theta(0),phi(1-$1/29))' \
68 -e '$3=30.75' -f basin.cal )
69
70 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.
71
72 #### Primitives
73 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:
74
75 modifier type identifier
76 n S1 S2 S3 ..Sn
77 0
78 m R1 R2 R3 ..Rm
79
80 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.
81
82 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.
83
84 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.
85
86 #### Aliases
87 An alias simply associates a new modifier and identifier with a previously defined primitive. The syntax is as follows:
88
89 modifier alias new_identifier old_identifier
90
91
92 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`.
93
94 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.
95
96 ### Scene Hierarchy
97 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.
98
99 ### *Radiance* Programs
100 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.
101
102 |Program|Read|Write|Function|
103 |-------|----|-----|--------|
104 **arch2rad** ||X|Convert Architrion text file to *Radiance*
105 **genblinds**||X|Generate curved venetian blinds
106 **genbox** ||X|Generate parallelepiped
107 **genclock** ||X|Generate analog clock
108 **genprism** ||X|Generate extruded polygon
109 **genrev** ||X|Generate surface of revolution
110 **gensky** ||X|Generate CIE sky distribution
111 **gensurf** ||X|Generate arbitrary surface patch
112 **genworm** ||X|Generate varying diameter curved path
113 **ies2rad** ||X|Convert IES luminaire file to *Radiance*
114 **mgf2rad** ||X|Convert MGF file to *Radiance*
115 **mkillum** |X|X|Compute *illum* secondary sources
116 **nff2rad** ||X|Convert NFF file to *Radiance*
117 **objline** ||X|Generate line drawing of *Radiance* file
118 **objview** ||X|Quick view of *Radiance* object
119 **oconv** ||X|Compile *Radiance* scene description
120 **obj2rad** ||X|Convert Wavefront .OBJ file to *Radiance*
121 **rad** |X|| Render *Radiance* scene
122 **rad2mgf** |X|| Convert *Radiance* file to MGF
123 **raddepend** |X|| Determine scene file dependencies
124 **replmarks** |X|X| Replace triangular markers with objects
125 **rpict** |X|| Batch rendering program
126 **rtrace** |X|| Customizable ray-tracer
127 **rview** |X|| Interactive renderer
128 **thf2rad** ||X| Convert GDS things file to *Radiance*
129 **tmesh2rad**||X| Convert triangle mesh file to *Radiance*
130 **xform** |X|X|Transform Radiance objects
131
132 **Table 1.** Radiance programs that read and write scene descriptions.
133
134 ### *Radiance* C Library
135 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.
136
137 ## Function File Format (.cal suffix)
138 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.
139
140 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:
141
142 {
143 basin.cal - calculate coordinates for basin sink.
144 }
145
146 theta(s) = PI*(0.5+0.5*s);
147 phi(t) = 2*PI*t;
148
149 R(th,p) = 5 + ( 3.25*cos(p)^2 +
150 1.75*sin(p)^2 ) * sin(th)^2;
151
152 x(th,p) = R(th,p)*sin(th)*cos(p);
153 y(th,p) = R(th,p)*sin(th)*sin(p);
154 z(th,p) = R(th,p)*cos(th);
155
156 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.)
157
158 [^2]: TBD - There once was a footnote here
159
160 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.
161
162 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:
163
164 !gensurf marble sink '15.5+x(theta(s),phi(t))' \
165 '10.5+y(theta(s),phi(t))' \
166 '30.75+z(theta(s),phi(t))' \
167 8 29 -f basin.cal -s
168
169 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.
170
171 ### Language Features
172
173 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!*):
174
175 fact(n) : if(n-1.5, n*fact(n-1), 1);
176
177 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
178 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.)
179
180 [^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.
181
182 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:
183
184 FTINY : 1e-7;
185 d1(f,x) = (f(x+FTINY)-f(x-FTINY))/FTINY/2;
186
187 Evaluating `d1(sin,1.1)` using this formula yields 0.4536, which is fairly close to the true derivative, which is `cos(1.1)`.
188
189 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:
190
191 v1, V.W, x_rand`local, `A_, Qa_5`
192
193 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.
194
195 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`.
196
197 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.
198
199 Other features of the language are truly transparent, but knowledge of them can help one to write more efficient function files:
200
201 - 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.
202
203 - 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.
204
205 ### Standard Definitions (Library)
206
207 The following are always defined:
208
209 `if(a, b, c)`
210 : Conditional expression. If a is positive, return b, else return c.
211
212 `select(N, a1, a2, ..)`
213 : Return Nth argument. If N is 0, then return the count of arguments excluding the first. This provides basic array functionality.
214
215 `sqrt(x)`
216 : Return square root of `x`, where `x >= 0`.
217
218 `sin(x), cos(x), tan(x), asin(x), acos(x), atan(x), atan2(y,x)`
219 : Standard trigonometry functions.
220
221 `floor(x), ceil(x)`
222 : Greatest lower bound and least upper bound (integer).
223
224 `exp(x), log(x), log10(x)`
225 : Exponent and logarithm functions.
226
227 `rand(x)`
228 : Return pseudo-random number in the range [0,1) for any argument x. The same return value is guaranteed for the same argument.
229
230 The following are sometimes defined, depending on the program:
231
232 `PI`
233 : The ratio of a circle's circumference to its diameter.
234
235 `erf(z), erfc(z)`
236 : Error function and complimentary error function.
237
238 `j0(x), j1(x), jn(n,x), y0(x), y1(x), yn(n,x)`
239 : Bessel functions.
240
241 `hermite(p0,p1,r0,r1,t)`
242 : One-dimensional Hermite polynomial.
243
244 The rendering programs also define the following noise functions:
245
246 `noise3(x,y,z), noise3x(x,y,z), noise3y(x,y,z), noise3z(x,y,z)`
247 : Perlin noise function and its gradient [Perlin85][Arvo91,p.396].
248
249 `fnoise3(x,y,z)`
250 : Fractal noise function, ranging from -1 to 1.
251
252 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:
253
254 `Dx, Dy, Dz`
255 : ray direction
256
257 `Nx, Ny, Nz`
258 : surface normal
259
260 `Px, Py, Pz`
261 : intersection point
262
263 `T`
264 : distance from start
265
266 `Ts`
267 : single ray (shadow) distance
268
269 `Rdot`
270 : ray dot product
271
272 `S`
273 : world scale
274
275 `Tx, Ty, Tz`
276 : world origin
277
278 `Ix, Iy, Iz`
279 : world i unit vector
280
281 `Jx, Jy, Jz`
282 : world j unit vector
283
284 `Kx, Ky, Kz`
285 : world k unit vector
286
287 `arg(n)`
288 : real arguments, arg(0) is count
289
290 For BRDF primitives, the following variables are also available:
291
292 `NxP, NyP, NzP`
293 : perturbed surface normal
294
295 `RdotP`
296 : perturbed ray dot product
297
298 `CrP, CgP, CbP`
299 : perturbed material color
300
301 For prism1 and prism2 primitives, the following are available:
302
303 `DxA, DyA, DzA`
304 : direction to target light source
305
306 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].
307
308 [^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.
309
310 ### *Radiance* Programs
311 Table 2 shows *Radiance* programs that read and write function files.
312
313 |Program | Read | Write | Function
314 |--------|------|-------|---------
315 **calc** | X |X | Interactive calculator
316 **genrev** | X || Generate surface of revolution
317 **gensurf** | X || Generate arbitrary surface patch
318 **genworm** | X || Generate varying diameter curved path
319 **macbethcal** || X | Compute image color & contrast correction
320 **pcomb**| X || Perform arbitrary math on picture(s)
321 **rcalc**| X || Record stream calculator
322 **rpict**| X || Batch rendering program
323 **rtrace** | X || Customizable ray-tracer
324 **rview**| X || Interactive renderer
325 **tabfunc** || X | Create function file from tabulated data
326
327 **Table 2.** Programs in the *Radiance* distribution that read and write function files.
328
329 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.
330
331 ### *Radiance* C Library
332 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:
333
334 `typedef struct epnode EPNODE;`
335 : 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.
336
337 `(double) evalue(ep);`
338 : 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)`.)
339
340 `extern unsigned long eclock;`
341 : 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.
342
343 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.
344 Following are standard routines provided for parsing from a file and parsing from a string:
345
346 `EPNODE *eparse(char *expr);`
347 : Compile the string expr into a parse tree for later evaluation with evalue(ep).
348
349 `epfree(EPNODE *ep);`
350 : Free memory associated with ep, including any variables
351 referenced if they are no longer defined.
352
353 `double eval(char *expr);`
354 : Immediately parse, evaluate and free the given string expression.
355
356 `fcompile(char *fname);`
357 : Compile definitions from the given file, or standard input if fname is NULL.
358
359 `scompile(char *str, char *fn, int ln);`
360 : 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.
361
362 The following routines allow one to control the current context for definition lookup and storage:
363
364 `char *setcontext(char *ctx);`
365 : Set the current context to ctx. If ctx is NULL, then simply return the current context. An empty string sets the global context.
366
367 `char *pushcontext(char *name);`
368 : Push another context onto the stack. Return the new (full)
369 context.
370
371 `char *popcontext();`
372 : Pop the top context name off the stack. Return the new (full) context.
373
374 The following functions permit the explicit setting of variable and function values:
375
376 `varset(char *vname, int assign, double val);`
377 : 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.
378
379 `funset(char *fname, int nargs, int assign, double (*fptr)(char *fn));`
380 : 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.
381
382 The following functions are provided for evaluating a function or variable in the current definition set:
383
384 `double varvalue(char *vname);`
385 : 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.
386
387 `double funvalue(char *fn, int n, double a);`
388 : 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.
389
390 These routines can be used to check the existence of a specific function or variable:
391
392 `int vardefined(char *vname);`
393 : Return non-zero if the named variable is defined. (If the symbol
394 is defined as a function, zero is returned.)
395
396 `int fundefined(char *fname);`
397 : 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.)
398
399 These routines allow definitions to be cleared:
400
401 `dclear(char *dname);`
402 : Clear the given variable or function, unless it is a constant expression.
403
404 `dremove(char *dname);`
405 : 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.
406
407 `dcleanup(int level);`
408 : 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.
409
410 These routines may be used during library function evaluation:
411
412 `int nargum();`
413 : Determine the number of arguments available in the current
414 function evaluation context.
415
416 `double argument(int n);`
417 : Evaluate and return the nth argument.
418
419 `char *argfun(n);`
420 : Get the name of the function passed as argument n. (Generates an error if the nth argument is not a function.)
421
422 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:
423
424 `-DVARIABLE`
425 : Allow user-defined variables and (if `-DFUNCTION`) user-
426 defined functions.
427
428 `-DFUNCTION`
429 : Compile in library functions and (if `-DVARIABLE`) allow user-supplied function definitions.
430
431 `-DBIGLIB`
432 : 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`.
433
434 `-DRCONST`
435 : Reduce constant subexpressions during compilation. This can result in substantial savings during later evaluation, but the original user-supplied expressions are lost.
436
437 `-DREDEFW`
438 : 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.)
439
440 `-DINCHAN`
441 : Provide for `\$N` syntax for input channels, which result in callbacks to client-supplied chanvalue(n) routine on each evaluation.
442
443 `-DOUTCHAN`
444 : 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.
445
446 ## Data File Format (.dat suffix)
447 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.
448
449 ![Division of axes in .dat file](figure1.svg)
450
451 **Figure 1.** A 2-dimensional grid with one regularly divided axis and one irregularly divided axis. Each intersection corresponds to a data value that
452 appears in the file.
453
454 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.
455
456 A file corresponding to the topology shown in Figure 1 is:
457
458 ######### Header ########
459 2 # Two-dimensional data array
460 0.5 0.1 5 # The regularly spaced axis
461 0 0 5 3 5 10 16 20 # The irregularly spaced axis
462 ########## Body #########
463 # The data values, starting with the
464 # upper left, moving right then down:
465 19.089 7.001 14.647 6.3671 8.0003
466 3.8388 11.873 19.294 16.605 2.7435
467 16.699 6.387 2.8123 16.195 17.615
468 14.36 14.413 16.184 15.635 4.5403
469 3.6740 14.550 10.332 15.932 1.2678
470
471 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.
472
473 ### *Radiance* Programs
474 Table 3 shows *Radiance* programs that read and write data files.
475
476 Program | Read | Write | Function
477 ----------- | ---- | ----- | --------
478 **ies2rad** || X | Convert IES luminaire file to *Radiance*
479 **mgf2rad** || X | Convert MGF file to *Radiance*
480 **rpict** | X || Batch rendering program
481 **rtrace** | X || Customizable ray-tracer
482 **rview** | X || Interactive renderer
483
484 **Table 3.** Programs in the *Radiance* distribution that read and write data files.
485
486 ### *Radiance* C Library
487 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).
488
489 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`.
490
491 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`.
492
493 ## Font File Format (.fnt suffix)
494 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".
495
496 ![Drawing of an A, based on coordinates](figure2.svg)
497
498 **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.
499
500 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:
501
502 65 15 # Helvetica "A"
503 155 222 242 48 185 48 168 86
504 83 86 65 48 12 48 101 222
505 155 222 128 179 126 179 97 116
506 155 116 128 179 155 222
507
508 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.
509
510 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.
511
512 ### *Radiance* Programs
513 Table 4 shows *Radiance* programs that read and write font files.
514
515 Program | Read | Write | Function
516 ----------- | ---- | ----- | --------
517 **pcompos** | X || Compose *Radiance* pictures
518 **psign** | X || Generate *Radiance* picture label
519 **rpict** | X || Batch rendering program
520 **rtrace** | X || Customizable ray-tracer
521 **rview** | X || Interactive renderer
522
523 **Table 4.** Programs in the *Radiance* distribution that read and write font files.
524
525 ### *Radiance* C Library
526 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`.
527
528 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**.
529
530 ### Octree Format (.oct suffix)
531 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.
532
533 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.
534
535 ![A quadtree dividing two-dimensional space](figure3.svg)
536
537 **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.
538
539 ### Basic File Structure
540 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.
541
542 #### Information Header
543 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**:
544
545 #?RADIANCE
546 oconv model.b90 desk misc
547 oconv -f -i modelb.oct window blinds lights lamp
548 FORMAT=Radiance_octree
549
550 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.
551
552 #### Scene Boundaries
553 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:
554
555 | | |
556 |---|---|
557 285 | Two-byte object indices.
558 287 | Four-byte object indices.
559 291 | Eight-byte object indices. (Only supported on architectures with 64-bit **longs**.)
560
561 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.
562
563 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.)
564
565 #### Scene File Names
566 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).
567
568 #### Octree Data Structure
569 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].
570
571 [^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.
572
573 After the primitive count, the actual octree is stored, using the following recursive procedure:
574
575 puttree(ot) begin
576 if ot is a tree then
577 write the character '\002'
578 call puttree on each child node (0-7) else if ot is empty then
579 write the character '\000'
580 else
581 write the character '\001'
582 write out the number of surfaces
583 write out each surface's index
584 end
585 end puttree
586
587 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.
588
589 #### Compiled Scene Data
590 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.
591
592 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`.
593
594 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).
595
596 ### *Radiance* Programs
597 Table 5 shows *Radiance* programs that read and write octree files.
598
599 Program | Read | Write | Function
600 --------|------|-------|---------
601 **getinfo** | X | | Print information header from binary file
602 **oconv** | X | X | Compile *Radiance* scene description
603 **rad** | X | X | Render *Radiance* scene
604 **rpict** | X | | Batch rendering program
605 **rpiece** | X | | Parallel batch rendering program
606 **rtrace** | X | | Customizable ray-tracer
607 **rview** | X | | Interactive renderer
608
609 **Table 5.** Programs in the *Radiance* distribution that read and write octree files.
610
611 ### *Radiance* C Library
612 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.
613
614 Here is the main call for writing out an octree:
615
616 `writeoct(int store, CUBE *scene, char *ofn[]);`
617 : 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.
618
619 Here is the main call for reading in an octree:
620
621 `readoct(char *fname, int load, CUBE *scene, char *ofn[]);`
622 : 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.
623
624 ## Picture File Format (.hdr suffix)
625 *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^.
626
627 [^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."
628
629 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.
630
631 ### Basic File Structure
632 *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.
633
634 #### Information Header
635 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:
636
637 `FORMAT`
638 : 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.
639
640 `EXPOSURE`
641 : 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.
642
643 `COLORCORR`
644 : 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.)
645
646 `SOFTWARE`
647 : The software version used to create the picture, usually something like `RADIANCE 3.04 official release July 16, 1996`.
648
649 `PIXASPECT`
650 : 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.
651
652 `VIEW`
653 : The *Radiance* view parameters used to create this picture. Multiple assignments are cumulative inasmuch as new view options add to or override old ones.
654
655 `PRIMARIES`
656 : 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.
657
658 As always, the end of the header is indicated by an empty line.
659
660 #### Resolution String
661 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.
662
663 ![Radiance picture coordinate system](figure4.svg)
664
665 **Figure 4.** The standard coordinate system for an MxN picture.
666
667 The resolution string is given as one of the following:
668
669 `-Y N +X M`
670 : 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.
671
672 `-Y N -X M`
673 : The X ordering has been reversed, effectively flipping the image
674 left to right from the standard ordering.
675
676 `+Y N -X M`
677 : The image has been flipped left to right and also top to bottom, which is the same as rotating it by 180 degrees.
678
679 `+Y N +X M`
680 : The image has been flipped top to bottom from the standard
681 ordering.
682
683 `+X M +Y N`
684 : The image has been rotated 90 degrees clockwise.
685
686 `-X M +Y N`
687 : The image has been rotated 90 degrees clockwise, then flipped
688 top to bottom.
689
690 `-X M -Y N`
691 : The image has been rotated 90 degrees counter-clockwise.
692
693 `+X M -Y N`
694 : The image has been rotate 90 degrees counter-clockwise, then flipped top to bottom.
695
696 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.
697
698 #### Scanline Records
699 *Radiance* scanlines come in one of three flavors, described below:
700
701 Uncompressed
702 : 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.
703
704 Old run-length encoded
705 : 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.
706
707 New run-length encoded
708 : 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.
709
710 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:
711
712 $$L_v = 179(0.265r + 0.670g + 0.065b)$$
713
714 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)`.
715
716 If the `FORMAT` string indicates XYZ data, then the units of the Y primary are already lm/sr/m^2^, so the above conversion is unnecessary.
717
718 ### *Radiance* programs
719 Table 6 shows the many programs that read and write *Radiance* pictures.
720
721 Program | Read | Write | Function
722 ----------------|------|-------|---------
723 **falsecolor** | X+ | X | Create false color image
724 **findglare** | X+ | | Find sources of discomfort glare
725 **getinfo** | X | | Print information header from binary file
726 **macbethcal** | X | X | Compute image color & contrast correction
727 **normpat** | X | X | Normalize picture for use as pattern tile
728 **objpict** | | X | Generate composite picture of object
729 **pcomb** | X+ | X | Perform arbitrary math on picture(s)
730 **pcond** | X+ | X | Condition a picture for display
731 **pcompos** | X | X | Composite pictures
732 **pextrem** | X+ | | Find minimum and maximum pixels
733 **pfilt** | X+ | X+ | Filter and anti-alias picture
734 **pflip** | X+ | X+ | Flip picture left-right and/or top-bottom
735 **pinterp** | X+ | X+ | Interpolate/extrapolate picture views
736 **protate** | X+ | X+ | Rotate picture 90 degrees clockwise
737 **psign** | | X | Create text picture
738 **pvalue** | X+ | X+ | Convert picture to/from simpler formats
739 **ra_avs** | X | X | Convert to/from AVS image format
740 **ra_pict** | X | X | Convert to/from Macintosh PICT2 format
741 **ra_ppm** | X | X | Convert to/from Poskanzer Port. Pixmap
742 **ra_pr** | X | X | Convert to/from Sun 8-bit rasterfile
743 **ra_pr24** | X | X | Convert to/from Sun 24-bit rasterfile
744 **ra_ps** | X | | Convert to B&W or color PostScript
745 **ra_rgbe** | X | X | Convert to/from uncompressed picture
746 **ra_t8** | X | X | Convert to/from Targa 8-bit format
747 **ra_t16** | X | X | Convert to/from Targa 16-bit and 24-bit
748 **ra_tiff** | X | X | Convert to/from TIFF 8-bit and 24-bit
749 **ra_xyze** | X | X | Convert to/from CIE primary picture
750 **rad** | | X+ | Render Radiance scene
751 **ranimate** | | X+ | Animate Radiance scene
752 **rpict** | X | X+ | Batch rendering program
753 **rpiece** | X | X+ | Parallel batch rendering program
754 **rtrace** | X | X+ | Customizable ray-tracer
755 **rview** | X | X+ | Interactive renderer
756 **vwright** | X | | Get view parameters and shift them
757 **xglaresrc** | X | | Display glare sources from **findglare**
758 **ximage** | X+ | | Display *Radiance* picture under *X11*
759 **xshowtrace** | X | | Show ray traces on *X11* display
760
761 **Table 6.** *Radiance* programs that read and write picture files. Pluses indicate when a program makes use of or preserves physical pixel values.
762
763 ### *Radiance* C Library
764 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.
765
766 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.
767
768 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:
769
770 `int checkheader(FILE *fin, char *fmt, FILE *fout);`
771 : Read the header information from `fin`, copying to `fout` (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.)
772
773 `int getheader(FILE *fp, int (*f)(), char *p);`
774 : 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.
775
776 `int isformat(char *s);`
777 : Returns non-zero if the line `s` is a `FORMAT` assignment.
778
779 `int formatval(char *r, char *s);`
780 : Returns the `FORMAT` value from line `s` in the string `r`. Returns
781 non-zero if `s` is a valid format line.
782
783 `fputformat(char *s, FILE *fp);`
784 : Put format assignment `s` to the stream `fp`.
785
786 `isexpos(s)`
787 : Macro returns non-zero if the line `s` is an `EXPOSURE` setting.
788
789 exposval(s)
790 : Macro returns **double** exposure value from line `s`.
791
792 `fputexpos(ex,fp)`
793 : Macro** | puts real exposure value `ex` to stream `fp`.
794
795 `iscolcor(s)`
796 : Macro returns non-zero if the line `s` is a `COLORCORR` setting.
797
798 `colcorval(cc,s)`
799 : Macro assign color correction value from line `s` in the `COLOR`
800 variable `cc`.
801
802 `fputcolcor(cc,fp)`
803 : Macro puts correction `COLOR` `cc` to stream `fp`.
804
805 `isaspect(s)`
806 : Macro returns non-zero if the line `s` is a `PIXASPECT` setting.
807
808 `aspectval(s)`
809 : Macro returns double pixel aspect value from line `s`.
810
811 `fputaspect(pa,fp)`
812 : Macro puts real pixel aspect value `pa` to stream `fp`.
813
814 `int isview(char *s);`
815 : Returns non-zero if header line `s` contains view parameters. Note that ``s` could be either a `VIEW` assignment or a rendering command.
816
817 `int sscanview(VIEW *vp, char *s);`
818 : Scan view options from the string `s` into the `VIEW` structure
819 pointed to by `vp`.
820
821 `fprintview(VIEW *vp, FILE *fp);`
822 : 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)`.
823
824 `isprims(s)`
825 : Macro returns non-zero if the line `s` is a `PRIMARIES` setting.
826
827 `primsval(p,s)`
828 : Macro assign color primitives from line `s` in the `RGBPRIMS`
829 variable `p`.
830
831 `fputprims(p,fp)`
832 : Macro puts color primitives `p` to stream `fp`.
833
834 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:
835
836 `fgetsresolu(rs,fp)`
837 : 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.
838
839 `fputsresolu(rs,fp)`
840 : Macro to write the `RESOLU` structure pointed to by rs to the
841 stream fp.
842
843 `scanlen(rs)`
844 : Macro to get the scanline length from the `RESOLU` structure
845 pointed to by `rs`.
846
847 `numscans(rs)`
848 : Macro to get the number of scanlines from the `RESOLU`
849 structure pointed to by `rs`.
850
851 `fscnresolu(slp,nsp,fp)`
852 : Macro to read in a resolution string from `fp` 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.
853
854 `fprtresolu(sl,ns,fp)`
855 : Macro to print out a resolution string for `ns` scanlines of length `sl` in standard English-text ordering to `fp`.
856
857 The file `src/common/color.c` contains the essential routines for reading and writing scanline records. Here are the relevant calls and macros:
858
859 `int freadcolrs(COLR *scn, int sl, FILE *fp);`
860 : 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.
861
862 `int fwritecolrs(COLR *scn, int sl, FILE *fp);`
863 : 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.
864
865 `int freadscan(COLOR *fscn, int sl, FILE *fp);`
866 : 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.
867
868 `int fwritescan(COLOR *fscn, int sl, FILE *fp);`
869 : 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.
870
871 `colval(col,p)`
872 : 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.
873
874 `colrval(clr,p)`
875 : 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.
876
877 `colr_color(COLOR col, COLR clr);`
878 : Convert the 4-byte pixel `clr` to a machine floating-point
879 representation and store the result in `col`.
880
881 `setcolr(COLR clr, double p1, p2, p3);`
882 : 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.
883
884 ## Z-buffer Format (.zbf suffix)
885 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.
886
887 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?]
888
889 ### *Radiance* programs
890 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:
891
892 % pvalue -h `getinfo -d < frame110.hdr` -r -b -df
893 frame110.zbf | falsecolor -m 1 -s 40 -l Meters >
894 frame110z.hdr
895
896 The **getinfo** program appearing in back-quotes was used to get the dimensions associated with the Z-buffer from its corresponding picture file.
897
898 Program | Read | Write | Function
899 --------|------|-------|---------
900 **pinterp** | X | X | Interpolate/extrapolate picture views
901 **pvalue** | X | X | Convert picture to/from simpler formats
902 **rad** | | X | Render Radiance scene
903 **ranimate** | X | X | Animate Radiance scene
904 **rpict** | | X | Batch rendering program
905 **rtrace** | | X | Customizable ray-tracer
906
907 **Table 7.** *Radiance* programs that read and write Z-buffer files.
908
909 ### *Radiance* C Library
910 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.
911
912 ## Ambient File Format (.amb suffix)
913 *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.
914
915 #### Information Header
916
917 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:
918
919 FORMAT=Radiance_ambval
920
921 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.
922
923 #### Magic Number
924 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.
925
926 #### Ambient Value Records
927 Ambient values are written to the file in no particular order. Each diffuse interreflection value in *Radiance* has the following members:
928
929 Level
930 : 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.
931
932 Weight
933 : The weighting value associated with this ray or ambient value. Similar to the level to avoid using inappropriate values from the cache.
934
935 Position
936 : The origin point of this interreflection calculation.
937
938 Direction
939 : The surface normal indicating the zenith of the sample hemisphere for this value.
940
941 Value
942 : The calculated indirect irradiance at this point, in w/m^2^ (RGB color).
943
944 Radius
945 : The cosine-weighted, harmonic mean distance to other surfaces visible from this point, used to decide point spacing.
946
947 Posgradient
948 : The position-based gradient vector, indicating how brightness changes as a function of position in the sample plane.
949
950 Dirgradient
951 : The direction-based gradient vector, indicating how brightness changes as a function of surface orientation.
952
953 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.
954
955 ### *Radiance* Programs
956 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.
957
958 Program | Read | Write | Function
959 -------------|------|-------|---------
960 **getinfo** | X | | Print information header from binary file
961 **lookamb** | X | X | Convert *Radiance* ambient file
962 **rad** | X | X | Render *Radiance* scene
963 **rpict** | X | X | Batch rendering program
964 **rpiece** | X | X | Parallel batch rendering program
965 **rtrace** | X | X | Customizable ray-tracer
966 **rview** | X | X | Interactive renderer
967
968 **Table 8.** Programs in the *Radiance* distribution that read and write ambient files.
969
970 ### *Radiance* C Library
971 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 `src/common/header.c`, similar to the method described for *Radiance* picture files. Here are the main calls from `src/rt/ambio.c`:
972
973 `putambmagic(FILE *fp);`
974 : Put out the appropriate two-byte magic number for a *Radiance* ambient file to the stream `fp`.
975
976 `int hasambmagic(FILE *fp);`
977 : Read the next two bytes from the stream `fp` and return non-zero
978 if they match an ambient file's magic number.
979
980 `int writeambval(AMBVAL *av, FILE *fp);`
981 : Write out the ambient value structure `av` to the stream `fp`, returning -1 if a file error occurred, or 0 normally.
982
983 `int readambval(AMBVAL *av, FILE *fp);`
984 : 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.
985
986 `int ambvalOK(AMBVAL *av);`
987 : 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.
988
989 ## Conclusion
990 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.