A FORTRAN Program to Copy a RIS8 from One File to Another
A C Program to Convert a Raw Palette and Raw Raster Image to HDF RIS8 Format
C Functions to Convert Floating-Point Data to
8-Bit Raster Data
Chapter Overview
This chapter discusses the purposes and use of raster image sets, which allow you to store an image, together with its dimensions and a palette, in an HDF file. This chapter specifically introduces and describes the two raster image set interfaces currently contained in the HDF library: RIS8 and RIS24.
Header Files
The header file dfrig.h contains the declarations and definitions that are used by the routines listed in this chapter. This file can, if needed, be included with your C source code, and in some cases also with FORTRAN code.
Raster Image Sets
A raster image set (RIS) is a set of tags and associated information required to store an image in an HDF file. In HDF, 8-bit raster image sets (RIS8) are used to store 8-bit raster images, and 24-bit raster image sets (RIS24) are used to store 24-bit raster images.
The HDF library currently contains routines for storing raw raster images in RIS8 or RIS24 format and for retrieving raster images from files containing raster image sets. These routines are callable from C and FORTRAN programs that have access to the library. They work on several computers, including Cray systems running UNICOS, Alliant, Vax, Sun, and Macintosh models.
Table 2.1 lists the long and short names and the functions of the RIS8 and RIS24 routines currently contained in the HDF library. The following sections provide descriptions and examples of these calling routines.
Table 2.1Raster Image Set Routines in the HDF Library
Long NameShort NameFunction
DFR8setpaletted8spalsets the default palette to be used for subsequent images.
DFR8putimaged8pimgwrites out the RIS8 for the image as the first image in the file.
DFR8addimaged8aimgappends the RIS8 for the image to the file.
DFR8getdimsd8gdimsretrieves the dimensions of the image and indicates whether a palette is associated and stored with the image.
Table 2.1Raster Image Set Routines in the HDF Library (Continued)
Long NameShort NameFunction
DFR8getimaged8gimgretrieves the image and any associated palette, and stores them in arrays.
DFR8restartd8firstgets the next get command to read from the first RIS8 in the file, rather than the next.
DF24setild2setilsets the interlace to be used when writing out the RIS24 for the image.
DF24addimaged2iaimgappends the RIS24 for the image to the file.
DF24getdimsd2igdimsretrieves the dimensions and interlace of the image.
DF24getimaged2igimgretrieves the image and stores it in an array.
DF24reqil(il)d2reqilspecifies an interlace to be used in place of the interlace indicated in the file when the next raster image is read.
Reasons to Use Raster Image Sets
When raster images are stored in the form of HDF raster image sets, it becomes possible to use a variety of software tools for displaying and manipulating them. NCSA Image, for instance, can operate directly on images stored in HDF raster image format. Other software can display raster images in HDF format on a variety of different machines.
By using HDF files with raster image sets, programmers are able to write portable software for working with the images much more easily than otherwise. When palette, dimension, or compression information is stored in the same file as the actual images, the software does not have to search elsewhere for this pertinent information. More importantly, you may be spared from having to supply the information. This reduction in the need to coordinate disparate pieces of information about a raster image can make the job of creating and running image-processing programs significantly easier.
8-Bit Raster Image Sets
The phrase, 8-bit raster image set (RIS8), refers to the set of tags and associated information required to store an 8-bit raster image in an HDF file. An RIS8 contains at least the first three of the following components and may also contain a palette:
ÑAn image-here, a two-dimensional array of 8-bit numbers, one for each pixel in the raster image, where pixel values range from 0 to 255 (Pixel values indicate to the hardware which colors to use when drawing the corresponding pixels on the screen.)
ÑDimensions-two values that represent the x and y dimensions of the image, respectively
ÑA compression scheme-a code that indicates if and how the image was compressed (See the following section, "Compression Schemes.╙)
ÑA palette-a lookup table with 256 entries that tells the color to associate with each of the 256 possible pixel values (Each entry in the palette is chosen from a master palette of 224 RGB colors. Each palette entry consists of three bytes, one each for red, green, and blue. The first three bytes represent the R, G, and B values of the first color in the palette; the next three the R, G, and B values of the second color; and so forth. The total size of a palette is 768 bytes.)
An example of an HDF file with two raster image sets is illustrated in Figure 2.1.
Figure 2.1Two Raster Image Sets in an HDF File
Compression Schemes
A compression scheme indicates if and how an image is compressed. Compression schemes currently supported by NCSA HDF are run length encoding and IMCOMP. The value of the integer argument compress determines which scheme, if any, is to be used, as shown in Table 2.2.
Table 2.2Compression Scheme Codes
ValueCompression Scheme
0none
DFTAG_RLErun length encoding (RLE)
DFTAG_IMCOMPIMCOMP
The HDF tags DFTAG_RLE and DFTAG_IMCOMP are defined as the values 11 and 12, respectively, in the file 'df.h'. You can avoid using numbers for compression codes if you include this file in your program.
A Note About RLE
The run length encoding (RLE) method used in HDF works as follows: Each sequence of pixels begins with a count byte. The low seven bits of the count byte indicate the number of bytes in the sequence (n). The high bit of the count byte indicates whether the next byte should be replicated n times (high bit=1), or whether the next n bytes should be included as is (high bit=0).
The amount of space saved by RLE depends upon how much repetition there is among the pixels in the rows. (Pixels are stored in rows.) If there is a great deal of repetition, much space is saved; if there is little repetion, the savings can be very small. In the worst case-when every pixel is different from the one that precedes it-an extra byte is added for every 127 bytes in the image.
A Note About IMCOMP
IMCOMP should be used with caution if you are concerned about losing information in your image. IMCOMP compression first breaks an image into 4 x 4 arrays of pixels, then for each array chooses two colors to distribute in the array. (These two colors are added to a 256-color palette that IMCOMP compression builds. This new palette is based on, but different from, the original palette assigned.) Each of the 16 pixels in the 4 x 4 array can now be represented by one bit (0=first color; 1=second color). In addition to these sixteen bits, there are two bytes that give the palette locations of the two colors that were assigned to the 4 x 4 array.
Since each 4 x 4 array uses only 4 bytes, IMCOMP stores an image at a cost of 2 bits per pixel, which is 25% of the original storage requirement for the 8-bit image. The drawback of this savings is loss of information-only two colors are allowed to occupy each 4 X 4 array of pixels-whereas in the original image, 16 colors could occupy the same space. For many images this cost is bearable and hardly noticable, but for some images, the results can be totally unrecognizable.
Also note that IMCOMP is dependent on the existence of a palette. If you are going to use IMCOMP, you must include a palette with your image.
Writing 8-Bit Raster Images to a File
DFR8setpalette
FORTRAN:
INTEGER FUNCTION DFR8setpalette(palette)
CHARACTER*1palette(768)-palette to go with image
C:
int DFR8setpalette(palette)
unsigned charpalette[768];/* palette to go with image */
Purpose: To indicate what palette, if any, is to be used for subsequent images.
Returns: 0 on success; -1 on failure.
The palette that is set here continues as the default palette until it is changed by a new call to the routine.
DFR8putimage
FORTRAN:
INTEGER FUNCTION DFR8putimage(filename, image, xdim, ydim, compress)
CHARACTER*64filename-name of file to store RIS8 in
INTEGERxdim, ydim-dimensions of image
CHARACTERimage(xdim,ydim)-array holding image to be put in file
INTEGERcompress-type of compression to use, if
any
C:
int DFR8putimage(filename, image, xdim, ydim, compress)
char*filename;/* name of file to store RIS8 in */
int32xdim, ydim;/* dimensions of image */
char*image;/* array with image to put in file */
intcompress;/* type of compression to use, if any */
Purpose: To write out the RIS8 for the image as the first image in the file.
Returns: 0 on success; -1 on failure.
If before the call to DFR8putimage there was other information in the file, the function overwrites that information.
The argument compress identifies the scheme to be used for compressing the data, if any. Refer to Table 2.2 for valid values of compress.
If IMCOMP compression is used, the image must include a palette. (See the discussion of 8-bit compression schemes in an earlier section.)
NOTE: DFR8addimage (see below) writes an image to a file by appending it, rather than overwriting it.
DFR8addimage
FORTRAN:
INTEGER FUNCTION DFR8addimage(filename,image,xdim,ydim, compress)
CHARACTER*64filename-name of file to add RIS8 to
INTEGERxdim, ydim-dimensions of the image
CHARACTERimage(xdim,ydim) -array holding image to be added
to file
INTEGERcompress-type of compression to use, if
any
C:
int DFR8addimage(filename,image,xdim,ydim,compress)
char*filename;/* name of file to add RIS8 to */
int32xdim, ydim;/* dimensions of the image */
char*image;/* array holding image to add to file */
intcompress;/* type of compression to use, if any */
Purpose: To append to the file the RIS8 for the image.
Returns: 0 on success; -1 on failure.
In all other respects, DFR8addimage is functionally equivalent to DFR8putimage.
Example: Writing a Palette and an Image in RIS8 Format
Figure 2.2 demonstrates in FORTRAN how a palette stored in the array colors and a raw image stored in the 400 x 600 array picture are written to a file in RIS8 format.
Figure 2.2Storing an RIS8
FORTRAN:
INTEGERDFR8setpalette, DFR8putimage
CHARACTER*1colors(768)
CHARACTER*1picture(400,600)
INTEGERret
ret = DFR8setpalette(colors)
ret = DFR8putimage('herfile.hdf',picture,400,600,0)
if (ret .ne. 0)
write(*,*) 'Error writing image to myfile.hdf.'
.
.
.
Remarks:
ÑThe RIS8 with this palette and image is stored as the first image in 'herfile.hdf'. Note that if something already existed in this file, it will be lost.
ÑThe image is not compressed in the file.
ÑThe palette is assumed to be organized in the manner described earlier: R, G, B (first color); R, G, B (second color); and so forth.
Example: Writing a Series of RIS8 Images
Figure 2.3 illustrates a series of FORTRAN calls in which four 800 x 1200 images are written to the same file. The first two use palette palA and are compressed using the IMCOMP technique; the third and fourth use palette palB and are not compressed.
Figure 2.3Storing Multiple RIS8s in a Single File
FORTRAN:
INTEGERDFR8setpalette, DFR8putimage, DFR8addimage
CHARACTER*1palA(768), palB(768)
CHARACTER*1pic1(800,1200), pic2(800,1200)
CHARACTER*1pic3(800,1200), pic4(800,1200)
INTEGERret
INTEGERDFTAG_IMCOMP
DATADFTAG_IMCOMP/12/
ret = DFR8setpalette(palA)
ret = DFR8putimage('myfile',pic1,800,1200,DFTAG_IMCOMP)
ret = DFR8addimage('myfile',pic2,800,1200,DFTAG_IMCOMP)
ret = DFR8setpalette(palB)
ret = DFR8addimage('myfile',pic3,800,1200,0)
ret = DFR8addimage('myfile',pic4,800,1200,0)
.
.
.
Reading 8-Bit Raster Images from a File
The two routines, DFR8getdims and DFR8getimage, are sufficient to read raster images from a file. If enough is known about the images and palettes, only the latter routine is needed.
DFR8getdims
FORTRAN:
INTEGER FUNCTION DFR8getdims(filename,xdim,ydim,ispalette)
CHARACTER*64filename-name of file with RIS8 image
INTEGERxdim, ydim-dimensions of the next image
INTEGERispalette-1 if there is a palette, else 0
C:
int DFR8getdims(filename,xdim,ydim,ispalette)
char *filename;/* name of file with RIS8 image */
int32*xdim, *ydim;/* dimensions of the next image */
int*ispalette;/* 1 if there is a palette, else 0 */
Purpose: To open the file with name filename, find the next image, retrieve the dimensions of the image in xdim and ydim, and tell, via ispalette, whether there is a palette associated with the image.
Returns: 0 on success; -1 on failure.
If the file is being opened for the first time, DFR8getdims returns information about the first image in the file. If an image has already been read, DFR8getdims finds the next image. Thus, images are read in the same order in which they were written to the file.
Normally, DFR8getdims is called before DFR8getimage so that if necessary, space allocations for the image and palette can be checked, and the dimensions can be verified. If this information is already known, DFR8getdims need not be called.
DFR8getimage
FORTRAN:
INTEGER FUNCTION DFR8getimage(filename, image, xdim, ydim, palette)
CHARACTER*64filename-name of file with RIS8 image
INTEGERxdim,ydim-dimensions of the next image
CHARACTER*1 image(xdim,ydim) -array that will hold the image
CHARACTER*1 palette(768)-palette to go with image
C:
int DFR8getimage(filename, image, xdim, ydim, palette)
char *filename;/* name of file with RIS8 image */
int32xdim, ydim;/* dimensions of the next image */
char*image;/* array that will hold image */
unsigned char*palette;/* palette to go with image */
Purpose: To retrieve the image and its palette, if it is present, and store them in the specified arrays.
Returns: 0 on success; -1 on failure.
If palette is NULL, no palette is loaded, even if there is one stored with the image. If the image in the file is compressed, DFR8getimage automatically decompresses it.
If DFR8getdims has not been called, DFR8getimage finds the next image in the same way that DFR8getdims does.
DFR8restart
FORTRAN:
INTEGER FUNCTION DFR8restart()
C:
int DFR8restart()
Purpose: To cause the next get to read from the first RIS8 in the file, rather than the RIS8 following the one that was most recently read
Returns: 0 on success; -1 on failure
Example: Reading in a Raster Image Set
Figure 2.4 shows a FORTRAN call that reads in an image when the dimensions are already known, and a palette is known to exist.
Figure 2.4Reading an RIS8: Dimensions and Presence of Palette Known
FORTRAN:
INTEGERDFR8getimage
CHARACTER*1image(256,512)
CHARACTER*1palette(768)
INTEGERret
ret = DFR8getimage('myfile.hdf',image,256,512,pal)
.
.
.
Remarks:
ÑThe RIS8, stored in a file called, 'myfile.hdf', is read into an array called image.
ÑThe raster image stored in the file is known to be 256 x 512 bytes.
ÑThe array image is a 256x512 array of 8-bit characters. It is assumed that the array is dimensioned to be exactly this size.
ÑThe parameter pal is a 768-byte array, three bytes per color, representing R, G, and B values, respectively, for each color.
ÑIf DFR8getimage executes successfully, the return value 0 is assigned to ret; otherwise, ╨1 is assigned.
Example: Reading in a Raster Image Set
Figure 2.5 demonstrates a pair of FORTRAN calls in which the size of the image is not known ahead of time, nor is it known whether a palette exists.
Figure 2.5Reading an RIS8: Dimensions and Presence of Palette Not Known
FORTRAN:
INTEGERDFR8getdims, DFR8getimage
INTEGERxsize, ysize, ispal, ret
CHARACTER*1image(xsize,ysize)
CHARACTER*1pal(768)
ret = DFR8getdims('myfile.hdf',xsize,ysize,ispal)
ret = DFR8getimage('myfile.hdf',image,xsize,ysize,pal)
.
.
.
Remarks:
ÑThe RIS8, stored in a file called, 'myfile.hdf', is read into an array called image.
ÑIf after calling DFR8getdims, ispal is 1, then the call to DFR8getimage causes a palette to be loaded into the array pal. If the value of ispal is not 1, then nothing is loaded into the array pal when DFR8getimage is called. If a palette is needed, then the program has to supply it.
ÑThe array image is an xsize x ysize array of 8-bit characters. It is assumed that the array is dimensioned to be exactly this size.
24-Bit Raster Image Sets
The phrase 24-bit raster image set (RIS24) refers to the set of tags and associated information required to store a 24-bit raster image in an HDF file. An RIS24 contains at least the following components:
ÑAn image-here, a two-dimensional array of 24-bit pixel representations, where each 24-bit pixel value has three 8-bit components: one each for the red, green, and blue (RGB) values of the pixel color. These RGB values may be arranged in the file in one of three different ways (see the following section, "Interlace Schemes").
ÑAn interlace scheme-a code that describes the order in which the pixel components are physically stored in the file (see the following section, "Interlace Schemes").
ÑDimensions-two values that represent the x and y dimensions of the image, respectively.
Interlace Schemes
An interlace scheme describes the way an image is stored in a file or in memory. NCSA HDF supports different interlace schemes because graphics applications and devices vary in the way they organize graphics images. By storing an image in a file using a scheme that is consistent with the expected application or device, you can achieve substantial improvements in performance. The value of the integer argument il determines which scheme is to be used, as shown in Table 2.3. The interlace schemes are described in the following sections.
Table 2.3Interlace Scheme Codes
Value of ilInterlace Scheme
0pixel
1scan-line
2scan-plane
Pixel Interlace Scheme
The default interlace scheme describes an image pixel-by-pixel. This scheme is called pixel interlace. The code to specify the pixel interlace scheme in an RIS24 is 0 (zero).
For example, by default, NCSA HDF assumes that a 100 x 200 image with three components (R, G, and B) is stored as an array of size 3 x 100 x 200, and that each element of this array is exactly one byte in size and contains an R, G, or B value.
Specifically, an interlace code of 0 indicates that the bytes that describe the image are stored in the following order in the file or memory:
R, G, and B values are stored, in that order, in the first three bytes of the first row of the array, corresponding to the first pixel in the first row of the image.
R, G, and B values are stored in the second three bytes of the first row of the array, corresponding to the second pixel in the first row of the image.
And so forth, until the RGB values for the 100 pixels of the first row of the image are stored. This process is repeated until the RGB values for each pixel in the 200 lines of the image are stored.
Scan-Line Interlace Scheme
The scan-line interlace scheme describes an image line-by-line. The code to specify the scan-line interlace scheme is 1.
For example, an interlace scheme code of 1 for a 100 x 200 image with three components (R, G, and B) informs NCSA HDF to assume that the image is stored as an array of size 100 x 3 x 200.
Specifically, an interlace code of 1 indicates that the bytes that describe the image are stored in the following order in the file or memory: 100 R values are stored consecutively in the first row of the array for each of the pixels in the first line of the image, then 100 G values are stored in the second row of the array for each of the pixels in the first line of the image, then 100 B values are stored in the third row of the array for each of the pixels in the first line of the image, and so forth, until the RGB values for each of the 200 lines of pixels in the image are stored.
Scan-Plane Interlace Scheme
The scan-plane interlace scheme describes an image color component-by-color component. The code to specify the scan-plane interlace scheme is 2.
For example, an interlace scheme code of 2 for a 100 x 200 image with three components (R, G, and B) informs NCSA HDF to assume that the image is stored as an array of size 100 x 200 x 3.
Specifically, an interlace code of 2 indicates that the bytes that describe the image are stored in the following order in the file or memory: R values are stored in the first 100 x 200 bytes of the array for each of the pixels in the image; the G values for the image are stored in the second 100 x 200 plane; and the B values in the third.
Figure 2.6 illustrates how an RIS24 -- stored using the scan-plane interlace -- looks in an HDF file.
Figure 2.6Scan-Plane Interlace
Compression Schemes
As of this writing, image compression has not been implemented for 24-bit images in HDF. However, there are plans to implement a routine to cause 24-bit images to be stored in compressed mode. This routine should be available in the next release of HDF.
Writing 24-Bit Raster Images to a File
DF24setil
FORTRAN:
INTEGER FUNCTION DF24setil(il)
INTEGER il;- interlace of image
C:
int DF24setil(il)
int il;/* interlace of image */
Purpose: To set interlace scheme to be used on subsequent writes.
Returns: 0 on success; ╨1 on failure with DFerror set.
If DF24setil is not called, the interlace code is assumed to be 0. Interlace codes: 0 = pixel interlacing; 1 = scan-line interlacing;
2 = scan-plane interlacing.
DF24addimage
FORTRAN:
INTEGER FUNCTION DF24addimage(name, image, xdim, ydim)
CHARACTER*(*) name
CHARACTER *(*)image
INTEGER xdim, ydim
C:
int DF24addimage(filename, image, xdim, ydim)
char *filename;/* name of HDF file */
char *image;/* pointer to space for return image */
int32 xdim, ydim;/* dimensions of array image */
Purpose: To write out a 24-bit image.
Returns: 0 on success; ╨1 on failure with DFerror set.
Array image is assumed to be xdim x ydim x 3 bytes.
Example: Writing a RIS24 with the Default Pixel Interlace
The C code in Figure 2.7 demonstrates how the default pixel interlace is used when storing the 400 x 600 array picture in a file in RIS24 format.
Figure 2.7Storing an RIS24 Using Pixel Interlace
C:
intDF24putimage;
char*picture[3][400][600];
intret;
ret = DF24addimage("herfile.hdf",picture,400,600);
if (ret != 0)
printf("Error writing image to myfile.hdf.");
.
.
.
Example: Writing Several 24-bit Images
Figure 2.8 shows a series of C calls in which four 800 x 1200 images are written to the same file. The first two calls use the default interlace scheme; the second two calls use scan-line interlace.
Figure 2.8Storing Multiple RIS24s in a Single File
C:
intDF24addimage
charpic1[3][800][1200], pic2[3][800][1200]
charpic3[800][3][1200], pic4[800][3][1200]
DF24addimage('myfile',pic1,800,1200)
DF24addimage('myfile',pic2,800,1200)
DF24setil(1)
DF24addimage('myfile',pic3,800,1200)
DF24addimage('myfile',pic4,800,1200)
.
.
.
Reading 24-Bit Raster Images from a File
The two routines, DF24getdims and DF24getimage, are sufficient to read raster images from a file. If enough is known about the images and interlacing, only the latter routine is needed.
DF24getdims
FORTRAN:
INTEGER FUNCTION DF24getdims(name, xdim, ydim, il)
CHARACTER*(*) name-name of HDF file
INTEGER xdim, ydim-for returning x & y dimensions
INTEGER il-for returning interlace of image in file
C:
int DF24getdims(filename, pxdim, pydim, pil)
char *filename;/* name of HDF file */
int32 *pxdim, *pydim;/* pointers to locations for returning
x & y dimensions */
int *pil;/* location for returning interlace
of image in file */
Purpose: To get dimensions and interlace storage scheme of next image RIS.
Returns: 0 on success; ╨1 on failure with DFerror set.
If the file is being opened for the first time, DF24getdims returns information about the first image in the file. If an image has already been read, DF24getdims finds the next image. Thus, images are read in the same order in which they were written to the file.
If you know the dimensions of the image beforehand, there is no need to call DF24getdims. Simply allocate arrays with the proper dimensions for the image and let DF24getimage read in the images. If, however, you do not know the values of rows and cols, you must call DF24getdims to get them and then use them to determine the right amount of space needed for the array image.
Successive additional calls to DF24getdims and DF24getimage, respectively, retrieve all of the images in the file in the sequence in which they were written.
INTEGER FUNCTION DF24getimage(name, image, xdim, ydim)
CHARACTER*(*) name-name of HDF file
CHARACTER*(*) image-pointer to space to return image
INTEGER xdim, ydim-dimensions of space to return image
C:
int DF24getimage(filename, image, xdim, ydim)
char *filename;/* name of HDF file */
char *image;/* pointer to space to return image */
int32 xdim, ydim;/* dimensions of space to return lut */
Purpose: To get image from next RIS.
Returns: 0 on success; ╨1 on failure with DFerror set.
If DFR8getdims has not been called, DFR8getimage finds the next image in the same way that DFR8getdims does.
The amount of space allocated for the image should be xdim x Idim x 3 bytes.
To specify that the next call to DF24getimage should read the raster image from the RIS24 using a particular interlace, rather than the interlace used to store the image in the file, make a call to DF24reqil (see below).
DF24reqil
FORTRAN:
INTEGER FUNCTION DF24reqil(il)
INTEGER il- interlace to get next image with
C:
int DF24reqil(il)
int il;/* interlace to get next image with */
Purpose: To cause next DF24getimage to store image with the specified interlace.
Returns: 0 on success; ╨1 on failure with DFerror set.
Regardless of what interlace scheme is used to store the image, DF24reqil causes the image to be loaded into memory, interlaced according to the specification of il.
NOTE: Since a call to DF24reqil may require a substantial reordering of the data, I/O performance could be adversely affected; e.g. it could result in much slower I/O performance than would be achieved if no change in interlace were requested.
Figure 2.9 shows a C call that reads in an image when the dimensions and interlace are already known.
Figure 2.9Reading an RIS24: Dimensions and Interlace Known
C:
intDF24getimage;
charimage[3][256][512];
DF24getimage("myfile.hdf",image,256,512);
.
.
.
Remarks:
ÑThe RIS8, stored in a file called 'myfile.hdf', is read into an array called image.
ÑThe raster image stored in the file is known to be 256 x 512.
ÑThe array image is a 3 x 256 x 512 array of 8-bit characters.
Example: Read an Image, Dimensions and Interlace Not Known
Figure 2.10 illustrates a set of C calls that read in an image, where the dimensions of the image and interlace scheme are not known ahead of time.
Figure 2.10Reading an RIS24: Dimensions and Interlace Not Known
C:
intDF24getdims, DF24getimage;
intxsize, ysize, ispal;
char*image; /* pointer to space to return image */
DF24getdims("myfile.hdf",xsize,ysize,il);
DF24reqil(2);
image = (char *) malloc(3*xsize*ysize);
DF24getimage("myfile.hdf",image,xsize,ysize);
.
.
.
Remarks:
ÑThe RIS24 is stored in a file called 'myfile.hdf' in an array called image.
ÑThe data is stored in the array image as if the array were three planes of size xsize x ysize.
ÑSince no explicit declaration is given for image, it is the responsibility of the program to compute offsets in the array that correspond to particular elements.
Sample Programs
A FORTRAN Program to Copy a RIS8 from One File to Another
This program reads into image1 an 8-bit raster image from an HDF file called 'testrig1.df'. At the same time, it reads a palette into the array palette. The dimensions of the image are read into rows and cols. It is assumed that the image is small enough to fit into the 150,000-character array image1; that is, the value rows*cols must be less than 150,000.
The program next writes out the palette and image to the file 'testrig2.df'. Since the compress parameter in DFR8putimage is 12, the output image is encoded using run length encoding.
(See Figure 2.11)
Figure 2.11 FORTRAN Program to Copy a RIS8 from One File to Another
FORTRAN:
PROGRAM RISexample
CHARACTER*1image1(150000)
CHARACTER*1palette(768)
INTEGERrows, cols, ispal
INTEGER ret
ret = DFR8getdims('testrig1.df', rows, cols, ispal)
ret = DFR8getimage('testrig1.df', image1, rows, cols, palette)
ret = DFR8setpalette(palette);
ret = DFR8putimage('testrig2.df',image1,rows,cols,12)
stop
end
A C Program to Convert a Raw Palette and Raw Raster Image to HDF RIS8 Format
The example in Figure 2.12 shows a complete program for processing RIS8 data. Several features of HDF image storage are illustrated here. The program does the following, in order:
ÑReads into image1 a 256 x 512 8-bit raster image from a non-HDF file called "denaa031"
ÑReads into each of red, green, and blue 256 values representing the palette from a file called "ps.pal" (The palette stored in "ps.pal" is not in HDF format, so it is rearranged into proper format in a new, 768-byte array called palette.)
ÑWrites the palette and image as a raster image set to a file called "testrig1.hdf"
ÑReads the palette and image back in, this time storing the image in image2 and storing the palette back in palette
ÑCompares the contents of image2 to the contents of image1 to determine whether they are identical, as they should be
Figure 2.12 C Program Dealing with Raster Image Sets
C:
#include "df.h"
main
{
unsigned char
image1[131072], /* raw image to be read in from denaa031,
then put into an RIS8 in testrig.df */
image2[131072], /* image to be read in from testrig.df */
palette[768],
reds[256], /* colors to be loaded into palette*/
greens[256],
blues[256],
*p;/* pointer to palette*/
int j;
int rows, cols,
ispal;/* boolean to tell if there is a palette*/
FILE *fp;
fp = fopen("denaa031","r"); /* read in raw 256x512 image */
fread(image1, 131072, 1, fp);
fclose(fp);
fp = fopen("ps.pal","r");/* read RGB values from palette file */
fread(reds,1,256,fp);
fread(greens,1,256,fp);
fread(blues,1,256,fp);
fclose(fp);
p = palette;
for (j=0; j<256; j++) {/* reorganize palette so that */
if (strncmp(image1, image2, 131072) ==0) printf("identical\n");
else printf("different\n");
}
C Functions to Convert Floating-Point Data to
8-Bit Raster Data
The two functions shown in Figure 2.13 convert a floating-point data array into an 8-bit raster array. Once converted, this raw raster array is ready to be stored in RIS8 format.
Figure 2.13Converting Floating-Point Data to RIS8
C:
/* floattor8.c
*/
#include "df.h"
#define CHAR_MAX255
/*
* floattoR8
* Convert a data array into a raster array by dividing the
* range in the data into 256 regions, numbering the regions
* from zero to 255, and assigning to each position in the
* raster array the number of the corresponding region.
*
* Assume that raster array allocated is big enough.
*/
floattoR8(data, raster, size, max, min)
float data[];
char raster[];
int size;
float max, min;
{
int32 i;
float32 step;
if ((max == 0) && (min == 0))
findMaxMin(data, size, &max, &min);
step = (max - min) / CHAR_MAX;
if (step == 0)
return(-1);
for(i=0;i<size;i++)
raster[i] = (char) ((data[i] - min) / step);
}
/*
* findMaxMin
* Finds the maximum and minimum values in a data array.