1
2                         DESIGN OF THE UTAH RLE FORMAT
3
4                               Spencer W. Thomas
5
6              University of Utah, Department of Computer Science
7
8
9
10
11
12
13
14
15                                   ABSTRACT
16
17      The  Utah  RLE  (Run Length Encoded) format is designed to provide an
18    efficient, device  independent  means  of  storing  multi-level  raster
19    images.    Images of arbitrary size and depth can be saved.  The design
20    of the format is presented, followed by  descriptions  of  the  library
21    routines used to create and read RLE format files.
22
231. Introduction
24  The Utah RLE (Run Length Encoded) format is designed to provide an efficient,
25device independent means of storing multi-level  raster  images.    It  is  not
26designed  for  binary  (bitmap) images.  It is built on several basic concepts.
27The central concept is that of a channel.  A channel corresponds  to  a  single
28color,  thus  there  are  normally  a  red channel, a green channel, and a blue
29channel.  Up to 255 color channels  are  available  for  use;  one  channel  is
30reserved  for  "alpha"  data.    Although  the format supports arbitrarily deep
31channels, the current implementation is restricted to 8 bits per channel.
32
33  Image data is stored in an RLE file in a scanline form,  with  the  data  for
34each  channel of the scanline grouped together.  Runs of identical pixel values
35are compressed into a count and a  value.    However,  sequences  of  differing
36pixels are also stored efficiently (not as a sequence of single pixel runs).
37
38  The  file  header  contains  a  large  amount of information about the image,
39including its size, the number of channels  saved,  whether  it  has  an  alpha
40channel,  an optional color map, and comments.  The comments may be used to add
41arbitrary extra information to the saved image.
42
43  A subroutine interface has been written to allow programs to read  and  write
44files  in  the  RLE  format.  Two interfaces are available, one that completely
45interprets the RLE file and returns scanline pixel data, and one that returns a
46list  of  "raw"  run  and  pixel  data.  The second is more efficient, but more
47difficult to use, the first is easy to use, but slower.
48
49  The Utah RLE format has been used to save images from many  sources,  and  to
50display  saved  images  on  many  different  displays  and  from many different
51computers.
52
532. Description of RLE Format
54  All data in the RLE file is treated as  a  byte  stream.    Where  quantities
55larger than 8 bits occur, they are written in PDP-11 byte order (low order byte
56first).
57
58  The RLE file consists of two parts, a header followed by scanline data.   The
59header contains general information about the image, while the scanline data is
60a stream of operations describing the image itself.
61
62
63
642.1. The Header
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89                         Figure 2-1:   RLE file header
90
91  The header has a fixed part and a variable part.  A diagram of the header  is
92shown  in  Figure  2-1.    The magic number identifies the file as an RLE file.
93Following this are the coordinates of the lower left corner of  the  image  and
94the size of the image in the X and Y directions.  Images are defined in a first
95quadrant coordinate system (origin at the  lower  left,  X  increasing  to  the
96right, Y increasing up.)  Thus, the image is enclosed in the rectangle
97
98    [xpos,xpos+xsize-1]X[ypos,ypos+ysize-1].
99
100The  position  and  size are 16 bit integer quantities; images up to 32K square
101may be saved (the sizes should not be negative).
102
103  A flags byte follows.  There are currently four flags defined:
104
105  ClearFirst   If this flag is set, the image rectangle should first be cleared
106               to the background color (q.v.) before reading the scanline data.
107
108  NoBackground If  this  flag  is set, no background color is supplied, and the
109               ClearFirst flag should be ignored.
110
111  Alpha        This flag indicates the presence of an  "alpha"  channel.    The
112               alpha channel is used by image compositing software to correctly
113               blend anti-aliased edges.  It is stored as channel -1 (255).
114
115  Comments     If this flag is set, comments are present in the  variable  part
116               of the header, immediately following the color map.
117
118  The next byte is treated as an unsigned 8 bit value, and indicates the number
119of color channels that were saved.  It  may  have  any  value  from  0  to  254
120(channel 255 is reserved for alpha values).
121
122  The  pixelbits  byte  gives the number of bits in each pixel.  The only value
123currently supported by the software is 8  (in  fact,  this  byte  is  currently
124ignored when reading RLE files).  Pixel sizes taking more than one byte will be
125packed low order byte first.
126
127  The next two bytes describe the size and shape of the color map.    Ncmap  is
128the  number  of  color  channels in the color map.  It need not be identical to
129ncolors, but interpretation of values of ncmap different from 0, 1, or  ncolors
130may  be  ambiguous,  unless  ncolors  is  1.  If ncmap is zero, no color map is
131saved.  Cmaplen is the log base 2 of the length of each channel  of  the  color
132map.  Thus, a value for cmaplen of 8 indicates a color map with 256 entries per
133channel.
134
135  Immediately following the fixed header is  the  variable  part  of  the  file
136header.  It starts with the background color.  The background color has ncolors
137entries; if necessary, it is filled out to an odd number of bytes with a filler
138byte  on  the  end  (since  the  fixed header is an odd number bytes long, this
139returns to a 16 bit boundary).
140
141  Following the background color is the color  map,  if  present.    Color  map
142values  are  stored as 16 bit quantities, left justified in the word.  Software
143interpreting the color map must apply a shift appropriate to the application or
144to  the  hardware  being  used.    This convention permits use of the color map
145without knowing the original output precision.  The channels  of  the  map  are
146stored  in  increasing  numerical  order  (starting  with  channel 0), with the
147entries of each channel stored also in increasing order  (starting  with  entry
1480).  The color map entries for each channel are stored contiguously.
149
150  Comments,  if  present,  follow  the color map.  A 16 bit quantity giving the
151length of the comment block comes first.  If the length is odd, a  filler  byte
152will  be  present  at the end, restoring the 16 bit alignment (but this byte is
153not part  of  the  comments).    The  comment  block  contains  any  number  of
154null-terminated text strings.  These strings will conventionally be of the form
155"name=value", allowing for easy retrieval of specific  information.    However,
156there  is  no restriction that a given name appear only once, and a comment may
157contain an arbitrary string.  The intent of  the  comment  block  is  to  allow
158information to be attached to the file that is not specifically provided for in
159the RLE format.
160
161
162
1632.2. The Scanline Data
164  The scanline data  consists  of  a  sequence  of  operations,  such  as  Run,
165SetChannel,  and  Pixels,  describing  the  actual  image.   An image is stored
166starting at the lower left corner and proceeding upwards in order of increasing
167scanline  number.    Each  operation  and  its associated data takes up an even
168number of bytes, so that all operations begin on a 16 bit boundary.  This makes
169the implementation more efficient on many architectures.
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185                    Figure 2-2:   RLE file operand formats
186
187  Each  operation  is  identified  by an 8 bit opcode, and may have one or more
188operands.  Single operand operations fit into a  single  16  bit  word  if  the
189operand  value is less than 256.  So that operand values are not limited to the
190range 0..255, each operation has a long variant, in which  the  byte  following
191the  opcode  is  ignored  and the following word is taken as a 16 bit quantity.
192The long variant of an opcode is indicated by  setting  the  bit  0x40  in  the
193opcode (this allows for 64 opcodes, of which 6 have been used so far.)  The two
194single operand formats are shown pictorially in Figure 2-2.
195
196  The individual operations will now be discussed in detail.  The  descriptions
197are  phrased  in  terms  of the actions necessary to interpret the file.  Three
198indices are necessary: the current channel, the scanline number, and the  pixel
199index.  The current channel is the channel to which data operations apply.  The
200scanline number is just the Y position of the scanline in the image.  The pixel
201index is the X position of the pixel within the scanline.  The operations are:
202
203  SkipLines    Increment  the  scanline  number  by  the  operand  value.  This
204               operation terminates the current  scanline.    The  pixel  index
205               should be reset to the xpos value from the header.
206
207  SetColor     Set  the  current  channel to the operand value.  This operation
208               does not have a long variant.  Note that an operand value of 255
209               will  be interpreted as a -1, indicating the alpha channel.  All
210               other operand values are positive.  The pixel index is reset  to
211               the xpos value.
212
213  SkipPixels   Skip over pixels in the current scanline.  Increment pixel index
214               by the operand value.   Pixels  skipped  will  be  left  in  the
215               background color.
216
217  PixelData    Following this opcode is a sequence of pixel values.  The length
218               of the sequence is given by the operand value.  If the length of
219               the  sequence  is  odd, a filler byte is appended.  Pixel values
220               are inserted into the scanline in increasing X order.  The pixel
221               index is incremented by the sequence length.
222
223  Run          This  is  the only two operand opcode.  The first operand is the
224               length (N) of the run.  The second operand is the  pixel  value,
225               followed  by  a  filler  byte  if necessary(E.g., a 16 bit pixel
226               value would not need a filler byte.).  The next N pixels in  the
227               scanline  are  set to the given pixel value.  The pixel index is
228               incremented by N, to point to the pixel following the run.
229
230  EOF          This opcode has no operand, and indicates the  end  of  the  RLE
231               file.    It  is  provided  so that RLE files may be concatenated
232               together  and  still  be  correctly  interpreted.    It  is  not
233               required,  a  physical end of file will also indicate the end of
234               the RLE data.
235
236
237
2382.3. Subroutine Interface
239  Two similar subroutine interfaces are provided for reading and writing  files
240in  the  RLE format.  Both read or write a scanline worth of data at a time.  A
241simple "row" interface communicates in terms of arrays of pixel values.  It  is
242simple  to  use,  but  slower  than  the  "raw" interface, which uses a list of
243"opcode" values as its communication medium.
244
245  In both cases, the interface must be initialized by calling a setup function.
246The two types of calls may be interleaved; for example, in a rendering program,
247the background could be written using  the  "raw"  interface,  while  scanlines
248containing image data could be converted with the "row" interface.  The package
249allows multiple RLE streams to be open simultaneously, as is necessary for  use
250in  a  compositing  tool,  for  example.  All data relevant to a particular RLE
251stream is contained in a "globals" structure.
252
253  The globals structure echoes the format of the RLE header.   The  fields  are
254described below:
255
256  dispatch     The  RLE  creation routines are capable of writing various types
257               of output files in addition to RLE.  This value is an index into
258               a dispatch table.  This value is initialized by sv_setup.
259
260  ncolors      The  number  of  color  channels in the output file.  Up to this
261               many color channels will be saved, depending on  the  values  in
262               the channel bitmap (see below).
263
264  bg_color     A  pointer  to  an  array  of  ncolors  integers  containing the
265               background color.
266
267  alpha        If this is non-zero, an  alpha  channel  will  be  saved.    The
268               presence  or  absence  of  an alpha channel has no effect on the
269               value in ncolors.
270
271  background   Indicates how to treat background pixels.  It has the  following
272               values:
273
274               0    Save all pixels, the background color is ignored.
275
276               1    Save  only  non-background pixels, but don't set the "clear
277                    screen" bit.  This indicates "overlay" mode, a  cheap  form
278                    of compositing (but see note below about this.)
279
280               2    Save  only  non-background  pixels, clear the screen to the
281                    background color before restoring the image.
282
283  xmin, xmax, ymin, ymax
284               Inclusive bounds of the image region being saved.
285
286  ncmap        Number of channels of color map to be saved.  The color map will
287               not be saved if this is 0.
288
289  cmaplen      Log base 2 of the number of entries in each channel of the color
290               map.
291
292  cmap         Pointer  to an array containing the color map.  The map is saved
293               in "channel major" order.  Each entry in the map  is  a  16  bit
294               value  with the color value left justified in the word.  If this
295               pointer is NULL, no color map will be saved.
296
297  comments     Pointer to an array of  pointers  to  strings.    The  array  is
298               terminated  by  a  NULL  pointer  (like  argv or envp).  If this
299               pointer is NULL or if the first pointer it points  to  is  NULL,
300               comments will not be saved.
301
302  fd           File  (FILE *) pointer to be used for writing or reading the RLE
303               file.
304
305  bits         A bitmap containing 256 bits.   A  channel  will  be  saved  (or
306               retrieved)  only  if the corresponding bit is set in the bitmap.
307               The alpha channel corresponds to bit 255.  The bitmap allows  an
308               application   to  easily  ignore  color  channel  data  that  is
309               irrelevant to it.
310
311  The globals structure also contains private data for use by the  RLE  reading
312and  writing  routines;  data  that  must be maintained between calls, but that
313applies to each stream separately.
314
315
316
3172.4. Writing RLE files
318  To create  a  run-length  encoded  file,  one  first  initializes  a  globals
319structure  with  the relevant information about the image, including the output
320file descriptor.  The output file should be open and empty.    Then  one  calls
321sv_setup:
322
323    sv_setup( RUN_DISPATCH, &globals );
324
325This  writes the file header and initializes the private portions of the global
326data structure for use by the RLE file writing routines.
327
328  The image data must be available or expressible in a scanline order (with the
329origin  at  the  bottom of the screen).  After each scanline is computed, it is
330written to the output file by calling one of sv_putrow  or  sv_putraw.    If  a
331vertical  interval  of  the  image  has  no  data, it may be skipped by calling
332sv_skiprow:
333
334    /* Skip nrow scanlines */
335    sv_skiprow( &globals, nrow );
336
337  If the image data for a scanline is available as an array  of  pixel  values,
338sv_putrow  should be used to write the data to the output file.  As an example,
339let us assume that we have a 512 pixel long scanline, with three color channels
340and no alpha data.  We could call sv_putrow as follows:
341
342    rle_pixel scandata[3][512], *rows[3];
343    int i;
344
345    for ( i = 0; i < 3; i++ )
346        rows[i] = scandata[i];
347    sv_putrow( rows, 512, &globals );
348
349Note  that sv_putrow is passed an array of pointers to vectors of pixels.  This
350makes it easy to pass  arbitrarily  many,  and  to  specify  values  of  rowlen
351different from the size of (e.g.) the scandata array.
352
353  The  first element of each row of pixels is the pixel at the xmin location in
354the scanline.  Therefore, when saving only  part  of  an  image,  one  must  be
355careful to set the rows pointers to point to the correct pixel in the scanline.
356
357  If  an  alpha  channel  is  specified  to  be saved, things get a little more
358complex.  Here is the same example, but now with an alpha channel being saved.
359
360    rle_pixel scandata[3][512],
361              alpha[512], *rows[4];
362    int i;
363
364    rows[0] = alpha;
365    for ( i = 0; i < 3; i++ )
366        rows[i+1] = scandata[i];
367    sv_putrow( rows+1, 512, &globals );
368
369The sv_putrow routine expects to find the pointer to the alpha channel  at  the
370-1  position in the rows array.  Thus, we pass a pointer to rows[1] and put the
371pointer to the alpha channel in rows[0].
372
373  Finally, after all scanlines have been written, we call sv_puteof to write an
374EOF opcode into the file.  This is not strictly necessary, since a physical end
375of file also indicates the end of the RLE data, but it is a good idea.
376
377  Here is a skeleton of an application that uses sv_putrow to save an image  is
378shown  in  Figure  2-3.    This example uses the default values supplied in the
379globals variable sv_globals, modifying it to indicate the presence of an  alpha
380channel.
381
382  Using  sv_putraw is more complicated, as it takes arrays of rle_op structures
383instead of just pixels.  If the data is already available in something close to
384this  form,  however,  sv_putraw will run much more quickly than sv_putrow.  An
385rle_op is a structure with the following contents:
386
387  opcode       The type of data.  One of ByteData or RunData.
388
389  xloc         The X location within the scanline at which this data begins.
390
391  length       The length of the data.  This is either  the  number  of  pixels
392               that  are  the  same  color,  for a run, or the number of pixels
393               provided as byte data.
394
395  pixels       A pointer to an array of pixel values.  This field is used  only
396               for the ByteData opcode.
397
398  run_val      The pixel value for a RunData opcode.
399
400  Since  there  is  no guarantee that the different color channels will require
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501    #include <svfb_global.h>
502
503    main()
504    {
505            rle_pixel scanline[3][512], alpha[512], *rows[4];
506            int y, i;
507
508            /* Most of the default values in sv_globals are ok */
509            /* We do have an alpha channel, though */
510            sv_globals.sv_alpha = 1;
511            SV_SET_BIT( sv_globals, SV_ALPHA );
512
513            rows[0] = alpha;
514            for ( i = 0; i < 3; i++ )
515                    rows[i+1] = scanline[i];
516
517            sv_setup( RUN_DISPATCH, &sv_globals );
518
519            /* Create output for 512 x 480 (default size) display */
520            for ( y = 0; y < 480; y++ )
521            {
522                    mk_scanline( y, scanline, alpha );
523                    sv_putrow( rows, 512, &sv_globals );
524            }
525            sv_puteof( &sv_globals );
526    }
527
528                   Figure 2-3:   Example of use of sv_putrow
529
530the same set of rle_ops to describe  their  data,  a  separate  count  must  be
531provided for each channel.  Here is a sample call to sv_putraw:
532
533    int nraw[3];    /* Length of each row */
534    rle_op *rows[3];/* Data pointers */
535    sv_putraw( rows, nraw, &globals );
536
537A  more  complete  example  of the use of sv_putraw will be given in connection
538with the description of rle_getraw, below.
539
540  Calls to sv_putrow and sv_putraw may be freely intermixed, as required by the
541application.
542
543
544
5452.5. Reading RLE Files
546  Reading  an  RLE  file  is much like writing one.  An initial call to a setup
547routine reads the file header and fills in the  globals  structure.    Then,  a
548scanline at a time is read by calling rle_getrow or rle_getraw.
549
550  The  calling  program  is  responsible for opening the input file.  A call to
551rle_get_setup will then read the header information and fill  in  the  supplied
552globals  structure.   The return code from rle_get_setup indicates a variety of
553errors, such as the input file not being an RLE file, or  encountering  an  EOF
554while reading the header.
555
556  Each time rle_getrow is called, it fills in the supplied scanline buffer with
557one scanline of image data and returns the Y position of  the  scanline  (which
558will  be  one  greater than the previous time it was called).  Depending on the
559setting of the background flag, the scanline buffer may or may not  be  cleared
560to the background color on each call.  If it is not (background is 0 or 1), and
561if the caller does not clear the buffer between scanlines,  then  a  "smearing"
562effect will be seen, if some pixels from previous scanlines are not overwritten
563by pixels on the current scanline.  Note that  if  background  is  0,  then  no
564background  color  was  supplied,  and  setting  background  to 2 to try to get
565automatic  buffer  clearing  will  usually  cause  a  segmentation  fault  when
566rle_getrow tries to get the background color through the bg_color pointer.
567
568  Figure  2-4  shows  an  example  of  the use of rle_getrow.  Note the dynamic
569allocation of scanline storage space, and compensation for presence of an alpha
570channel.    A subroutine, rle_row_alloc, is available that performs the storage
571allocation automatically.  It is described below.  If the  alpha  channel  were
572irrelevant,  the  macro  SV_CLR_BIT could be used to inhibit reading it, and no
573storage space would be needed for it.
574
575  The function rle_getraw is the inverse of sv_putraw.  When called,  it  fills
576in  the  supplied  buffer  with raw data for a single scanline.  It returns the
577                         15
578scanline y position, or 2   to indicate end of file.  It  is  assumed  that  no
579                                15
580image  will  have  more  than  2  -1 scanlines.  A complete program (except for
581error checking) that reads an RLE file  from  standard  input  and  produces  a
582negative image on standard output is shown in Figure 2-5.
583
584  The  functions  rle_row_alloc and rle_raw_alloc simplify allocation of buffer
585space for use by the rle routines.  Both use a supplied  globals  structure  to
586determine how many and which channels need buffer space, as well as the size of
587the buffer for each scanline.  The returned buffer pointers  will  be  adjusted
588for the presence of an alpha channel, if it is present.  Buffer space for pixel
589or rle_op data will be allocate only for those channels that have bits  set  in
590the  channel  bitmap.  The buffer space may be freed by calling rle_row_free or
591rle_raw_free, respectively.
592
5933. Comments, issues, and directions
594  Some comments on the file format and current subroutine implementation:
595
596   - The background color for the alpha channel is always 0.
597
598   - All channels must have the same number of bits.    This  could  be  a
599     problem  when  saving,  e.g.,  Z  values,  or  if more than 8 bits of
600     precision were desired for the alpha channel.
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701    /* An example of using rle_getrow */
702    /* Scanline pointer */
703    rle_pixel ** scan;
704    int i;
705
706    /* Read the RLE file from stdin */
707    rle_get_setup( &globals );
708
709    /* Allocate enough space for scanline data, including alpha channel */
710    /* (Should check for non-zero return, indicating a malloc error) */
711    rle_row_alloc( &globals, &scan );
712
713    /* Read scanline data */
714    while ( (y = rle_getrow( &globals, stdin, scan ) <= globals.sv_ymax )
715            /* Use the scanline data */;
716
717
718                   Figure 2-4:   Example of rle_getrow use.
719
720
721    #include <stdio.h>
722    #include <svfb_global.h>
723    #include <rle_getraw.h>
724
725    main()
726    {
727        struct sv_globals in_glob, out_glob;
728        rle_op ** scan;
729        int * nraw, i, j, c, y, newy;
730
731        in_glob.svfb_fd = stdin;
732        rle_get_setup( &in_glob );
733        /* Copy setup information from input to output file */
734        out_glob = in_glob;
735        out_glob.svfb_fd = stdout;
736
737        /* Get storage for calling rle_getraw */
738        rle_raw_alloc( &in_glob, &scan, &nraw );
739
740        /* Negate background color! */
741        if ( in_glob.sv_background )
742            for ( i = 0; i < in_glob.sv_ncolors; i++ )
743                out_glob.sv_bg_color[i] = 255 - out_glob.sv_bg_color[i];
744
745        /* Init output file */
746        sv_setup( RUN_DISPATCH, &out_glob );
747
748        y = in_glob.sv_ymin;
749        while ( (newy = rle_getraw( &in_glob, scan, nraw )) != 32768 ) {
750            /* If > one line skipped in input, do same in output */
751            if ( newy - y > 1 )
752                sv_skiprow( &out_glob, newy - y );
753            y = newy;
754            /* Map all color channels */
755            for ( c = 0; c < out_glob.sv_ncolors; c++ )
756                for ( i = 0; i < nraw[c]; i++ )
757                    switch( scan[c][i].opcode ) {
758                    case RRunDataOp:
759                        scan[c][i].u.run_val = 255 - scan[c][i].u.run_val;
760                        break;
761                    case RByteDataOp:
762                        for ( j = 0; j < scan[c][i].length; j++ )
763                            scan[c][i].u.pixels[j] =
764                                255 - scan[c][i].u.pixels[j];
765                        break;
766                    }
767            sv_putraw( scan, nraw, &out_glob );
768            /* Free raw data */
769            rle_freeraw( &in_glob, scan, nraw );
770        }
771        sv_puteof( &out_glob );
772
773        /* Free storage */
774        rle_raw_free( &in_glob, scan, nraw );
775    }
776
777
778            Figure 2-5:   Program to produce a negative of an image
779
780   - Pixels are skipped (by sv_putrow) only if all channel values  of  the
781     pixel are equal to the corresponding background color values.
782
783   - The current Implementation of sv_putrow skips pixels only if at least
784     2 adjacent pixels are  equal  to  the  background.    The  SkipPixels
785     operation   is   intended   for  efficiency,  not  to  provide  cheap
786     compositing.
787
788   - Nothing forces the image data to lie within the  bounds  declared  in
789     the header.  However, rle_getrow will not write outside these bounds,
790     to prevent core dumps.  No such protection is provided by rle_getraw.
791
792   - Images saved in RLE are usually about 1/3 their original size (for an
793     "average"  image).   Highly complex images may end up slightly larger
794     than they would have been if saved by the trivial method.
795
796  We have not yet decided how pixels with other than 8 bits  should  be  packed
797into  the file.  To keep the file size down, one would like to pack ByteData as
798tightly as possible.  However, for interpretation speed, it would  probably  be
799better to save one value in each (pixelbits+7)/8 bytes.
800
801  Some proposed enhancements include:
802
803   - A "ramp" opcode.  This specifies that pixel values should be linearly
804     ramped between two values  for  a  given  number  of  pixels  in  the
805     scanline.   This opcode would be difficult to generate from an image,
806     but if an application knew it was generating a ramp, it could produce
807     significant file size savings (e.g.  in Gouraud shaded images).
808
809   - Opcodes  indicating  that  the  current  scanline is identical to the
810     previous, or that it differs only slightly  (presumably  followed  by
811     standard  opcodes indicating the difference).  Detection of identical
812     scanlines is easy, deciding that a scanline differs  slightly  enough
813     to  warrant a differential description could be difficult.  In images
814     with  large  areas  with  little  change,  this  could  produce  size
815     savings(This  suggestion  was  inspired  by  a description of the RLE
816     format used at Ohio State University.)
817
818  The subroutine library is still missing some useful functions.  Some proposed
819additions are:
820
821   - Conversion from "raw" to "row" format, and back.  One could then view
822     sv_putrow as being a "raw" to "row" conversion followed by a call  to
823     sv_putraw,  and  rle_getrow as a call to rle_getraw followed by "row"
824     to "raw" conversion.
825
826   - A function to merge several channels of  "raw"  data  into  a  single
827     channel.   For example, this would take separate red, green, and blue
828     channels and combine them into a single RGB channel.  This  would  be
829     useful  for  RLE interpretation on devices that do not easily support
830     the separate channel paradigm, while preserving the efficiency of the
831     "raw" interface.  It could also be used to increase the efficiency of
832     a compositing program.
833
834  The Utah RLE format has developed and matured over  a  period  of  about  six
835years,  and  has  proven  to  be  versatile  and  useful  for a wide variety of
836applications that require  image  transmittal  and  storage.    It  provides  a
837compact,  efficiently  interpreted  image storage capability.  We expect to see
838continued development of capabilities  and  utility,  but  expect  very  little
839change in the basic format.
840
8414. Acknowledgments
842  This   work  was  supported  in  part  by  the  National  Science  Foundation
843(DCR-8203692 and DCR-8121750), the Defense Advanced  Research  Projects  Agency
844(DAAK11-84-K-0017), the Army Research Office (DAAG29-81-K-0111), and the Office
845of Naval Research (N00014-82-K-0351).  All opinions, findings,  conclusions  or
846recommendations  expressed in this document are those of the authors and do not
847necessarily reflect the views of the sponsoring agencies.
848
849                               Table of Contents
8501. Introduction                                                               0
8512. Description of RLE Format                                                  0
852     2.1. The Header                                                          0
853     2.2. The Scanline Data                                                   0
854     2.3. Subroutine Interface                                                1
855     2.4. Writing RLE files                                                   1
856     2.5. Reading RLE Files                                                   2
8573. Comments, issues, and directions                                           2
8584. Acknowledgments                                                            5
859
860                                List of Figures
861Figure 2-1:   RLE file header                                                 0
862Figure 2-2:   RLE file operand formats                                        0
863Figure 2-3:   Example of use of sv_putrow                                     2
864Figure 2-4:   Example of rle_getrow use.                                      3
865Figure 2-5:   Program to produce a negative of an image                       4
866