📄 rle.txt
字号:
map. cmap Pointer to an array containing the color map. The map is saved in "channel major" order. Each entry in the map is a 16 bit value with the color value left justified in the word. If this pointer is NULL, no color map will be saved. comments Pointer to an array of pointers to strings. The array is terminated by a NULL pointer (like argv or envp). If this pointer is NULL or if the first pointer it points to is NULL, comments will not be saved. fd File (FILE *) pointer to be used for writing or reading the RLE file. bits A bitmap containing 256 bits. A channel will be saved (or retrieved) only if the corresponding bit is set in the bitmap. The alpha channel corresponds to bit 255. The bitmap allows an application to easily ignore color channel data that is irrelevant to it. The globals structure also contains private data for use by the RLE readingand writing routines; data that must be maintained between calls, but thatapplies to each stream separately.2.4. Writing RLE files To create a run-length encoded file, one first initializes a globalsstructure with the relevant information about the image, including the outputfile descriptor. The output file should be open and empty. Then one callssv_setup: sv_setup( RUN_DISPATCH, &globals );This writes the file header and initializes the private portions of the globaldata structure for use by the RLE file writing routines. The image data must be available or expressible in a scanline order (with theorigin at the bottom of the screen). After each scanline is computed, it iswritten to the output file by calling one of sv_putrow or sv_putraw. If avertical interval of the image has no data, it may be skipped by callingsv_skiprow: /* Skip nrow scanlines */ sv_skiprow( &globals, nrow ); If the image data for a scanline is available as an array of pixel values,sv_putrow should be used to write the data to the output file. As an example,let us assume that we have a 512 pixel long scanline, with three color channelsand no alpha data. We could call sv_putrow as follows: rle_pixel scandata[3][512], *rows[3]; int i; for ( i = 0; i < 3; i++ ) rows[i] = scandata[i]; sv_putrow( rows, 512, &globals );Note that sv_putrow is passed an array of pointers to vectors of pixels. Thismakes it easy to pass arbitrarily many, and to specify values of rowlendifferent from the size of (e.g.) the scandata array. The first element of each row of pixels is the pixel at the xmin location inthe scanline. Therefore, when saving only part of an image, one must becareful to set the rows pointers to point to the correct pixel in the scanline. If an alpha channel is specified to be saved, things get a little morecomplex. Here is the same example, but now with an alpha channel being saved. rle_pixel scandata[3][512], alpha[512], *rows[4]; int i; rows[0] = alpha; for ( i = 0; i < 3; i++ ) rows[i+1] = scandata[i]; sv_putrow( rows+1, 512, &globals );The sv_putrow routine expects to find the pointer to the alpha channel at the-1 position in the rows array. Thus, we pass a pointer to rows[1] and put thepointer to the alpha channel in rows[0]. Finally, after all scanlines have been written, we call sv_puteof to write anEOF opcode into the file. This is not strictly necessary, since a physical endof file also indicates the end of the RLE data, but it is a good idea. Here is a skeleton of an application that uses sv_putrow to save an image isshown in Figure 2-3. This example uses the default values supplied in theglobals variable sv_globals, modifying it to indicate the presence of an alphachannel. Using sv_putraw is more complicated, as it takes arrays of rle_op structuresinstead of just pixels. If the data is already available in something close tothis form, however, sv_putraw will run much more quickly than sv_putrow. Anrle_op is a structure with the following contents: opcode The type of data. One of ByteData or RunData. xloc The X location within the scanline at which this data begins. length The length of the data. This is either the number of pixels that are the same color, for a run, or the number of pixels provided as byte data. pixels A pointer to an array of pixel values. This field is used only for the ByteData opcode. run_val The pixel value for a RunData opcode. Since there is no guarantee that the different color channels will require #include <svfb_global.h> main() { rle_pixel scanline[3][512], alpha[512], *rows[4]; int y, i; /* Most of the default values in sv_globals are ok */ /* We do have an alpha channel, though */ sv_globals.sv_alpha = 1; SV_SET_BIT( sv_globals, SV_ALPHA ); rows[0] = alpha; for ( i = 0; i < 3; i++ ) rows[i+1] = scanline[i]; sv_setup( RUN_DISPATCH, &sv_globals ); /* Create output for 512 x 480 (default size) display */ for ( y = 0; y < 480; y++ ) { mk_scanline( y, scanline, alpha ); sv_putrow( rows, 512, &sv_globals ); } sv_puteof( &sv_globals ); } Figure 2-3: Example of use of sv_putrowthe same set of rle_ops to describe their data, a separate count must beprovided for each channel. Here is a sample call to sv_putraw: int nraw[3]; /* Length of each row */ rle_op *rows[3];/* Data pointers */ sv_putraw( rows, nraw, &globals );A more complete example of the use of sv_putraw will be given in connectionwith the description of rle_getraw, below. Calls to sv_putrow and sv_putraw may be freely intermixed, as required by theapplication.2.5. Reading RLE Files Reading an RLE file is much like writing one. An initial call to a setuproutine reads the file header and fills in the globals structure. Then, ascanline at a time is read by calling rle_getrow or rle_getraw. The calling program is responsible for opening the input file. A call torle_get_setup will then read the header information and fill in the suppliedglobals structure. The return code from rle_get_setup indicates a variety oferrors, such as the input file not being an RLE file, or encountering an EOFwhile reading the header. Each time rle_getrow is called, it fills in the supplied scanline buffer withone scanline of image data and returns the Y position of the scanline (whichwill be one greater than the previous time it was called). Depending on thesetting of the background flag, the scanline buffer may or may not be clearedto the background color on each call. If it is not (background is 0 or 1), andif the caller does not clear the buffer between scanlines, then a "smearing"effect will be seen, if some pixels from previous scanlines are not overwrittenby pixels on the current scanline. Note that if background is 0, then nobackground color was supplied, and setting background to 2 to try to getautomatic buffer clearing will usually cause a segmentation fault whenrle_getrow tries to get the background color through the bg_color pointer. Figure 2-4 shows an example of the use of rle_getrow. Note the dynamicallocation of scanline storage space, and compensation for presence of an alphachannel. A subroutine, rle_row_alloc, is available that performs the storageallocation automatically. It is described below. If the alpha channel wereirrelevant, the macro SV_CLR_BIT could be used to inhibit reading it, and nostorage space would be needed for it. The function rle_getraw is the inverse of sv_putraw. When called, it fillsin the supplied buffer with raw data for a single scanline. It returns the 15scanline y position, or 2 to indicate end of file. It is assumed that no
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -