home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / formats / utahrle / spec / rle.txt < prev   
Text File  |  1994-06-01  |  32KB  |  724 lines

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